不在范围内:输入构造函数或类“-"(以及反转列表时的其他错误) [英] Not in scope: type constructor or class ‘-’ (and other errors while reversing a list)

查看:54
本文介绍了不在范围内:输入构造函数或类“-"(以及反转列表时的其他错误)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究七周内的七种语言"一书,Haskell上线第一天的问题之一是"编写一个接受列表并反向返回相同列表的函数".

I'm working through the "Seven Languages In Seven Weeks" book, and one of the questions in the first day of Haskell is to "Write a function that takes a list and returns the same list in reverse".

我的第一个实现效果很好:

My first implementation worked fine:

reverseList :: [a] -> [a]
reverseList [] = []
reverseList [x] = [x]
reverseList (h:t) = reverseList(t) ++ [h]

然后我想到了另一种方法,我试图将其实现为:

I then thought of another approach, which I tried to implement as:

reverseList1 :: [a] -> [a]
reverseList1 [] = []
reverseList1 [x] = [x]
reverseList1 l = last(l) :: reverseList1(take(length(l)-1)(l))

(即-取最后一个元素,然后将颠倒的first-all-but-one元素添加到该元素).但是,这在尝试加载文件时给了我一个错误(实际上是三个):

(That is - take the last element, then append to it the reversed first-all-but-one elements). However, this gave me an error (actually, three) when I tried to load the file:

[1 of 1] Compiling Day1             ( day1.hs, interpreted )

day1.hs:35:49: error: Not in scope: type constructor or class ‘-’
   |
35 |   reverseList1 l = last(l) :: reverseList1(take(length(l)-1)(l))
   |                                                 ^^^^^^^^^^^

day1.hs:35:49: error:
    Illegal operator ‘-’ in type ‘length (l) - 1’
      Use TypeOperators to allow operators in types
   |
35 |   reverseList1 l = last(l) :: reverseList1(take(length(l)-1)(l))
   |                                                 ^^^^^^^^^^^

day1.hs:35:59: error:
    Illegal type: ‘1’ Perhaps you intended to use DataKinds
   |
35 |   reverseList1 l = last(l) :: reverseList1(take(length(l)-1)(l))
   |                                                           ^
Failed, no modules loaded.


搜索不在范围内"错误提示我正在尝试使用未导入的内容-我不认为需要明确导入减",根据其他实验.


Googling for the "not in scope" error suggested that I'm trying to use something which hasn't been imported - I don't think that I need to explicitly import "subtract", based on other experiments.

我不明白第二个错误(使用TypeOperators允许类型中的运算符)-我从

I don't understand the second error (Use TypeOperators to allow operators in types) - I see from here that TypeOperators is a flag I can set on ghci, but I'm not trying to use an operator in a type - length(l)-1 is (to the best of my knowledge) an argument to take, not a type.

Google搜索也许您打算使用DataTypes"导致我在此处-我希望,我的代码不会像该示例那样破烂不堪,但是我可能同样一无所知!

Googling "perhaps you intended to use DataTypes" led me to here - I hope that my code won't be as ripped-apart as that example, but it's possible that I'm equally clueless!

基于最后一个示例此处,我也尝试过:

Based on the last example here, I also tried:

reverseList1 l = last(l) :: reverseList1(take(takeLength)(l))
  where takeLength = length(l)-1

((从无法匹配类型'a'"开始出现(很长!)错误)和

(which gave a (very lengthy!) error starting with "Couldn't match type 'a'") and

reverseList1 l =
  let takeLength = length(l)-1 in
  in last(l) :: reverseList1(take(takeLength)(l))

哪个给了

day1.hs:40:5: error: parse error on input ‘in’
   |
40 |     in last(l) :: reverseList1(take(takeLength)(l))
   |     ^^
Failed, no modules loaded.

推荐答案

列表是使用:构造的. :: 表示一种类型,因此Haskell尝试将其读取为一种类型,因此会出现错误.

Lists are constructed with :. :: denotes a type, and so Haskell tries to read it as a type, hence the error.

更正后的代码是:

reverseList1 :: [a] -> [a]
reverseList1 [] = []
reverseList1 [x] = [x]
reverseList1 l = last l : reverseList1 (take (length l - 1) l)

请注意使代码更具可读性的括号!

Note the bracketing that makes the code more readable!

在第二次尝试中,您在 in 中写了两次,解析器感到困惑.

In your second attempt, you write in twice and the parser gets confused.

更正后的代码是:

reverseList1 l =
  let takeLength = length l - 1
  in last l : reverseList1 (take takeLength) l


现在,该错误实际上很有趣. TypeOperators 扩展名是一种(毫不奇怪)允许在类型声明中使用中缀运算符的扩展名.


Now, the error is actually quite interesting. The TypeOperators extension is one that allows (unsurprisingly) infix operators in type declarations.

在这里,编译器注意到-看起来像是一个infix运算符,并且鉴于它的类型符号推断您可能打算使用 TypeOperators 扩展名.当然,这里不是这样!

Here, the compiler noticed that - looked like an infix operator, and given that it was in a type signaures inferred that you probably meant to use the TypeOperators extension. Of course, that wasn't the case here!

对于 DataKinds ,这是一个相当高级的扩展,允许您放置数据(例如 1 "Hello" 等)在类型上.我不会在这里确切使用它,但是编译器提到它的原因是您在类型签名中使用了 1 ,该签名只能与 DataKinds 扩展名.

As for DataKinds, that is a fairly advanced extension that allows you to put data (like 1, "Hello" etc.) in types. I won't go into exactly what it's used for here, but the reason that the compiler mentioned it is that you used 1 in a type signature, which can only be used with the DataKinds extension.

这篇关于不在范围内:输入构造函数或类“-"(以及反转列表时的其他错误)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆