Haskell 无效的类型签名

4

简单的问题,这个有什么问题吗?

(get) :: [a] -> Int -> a   -- <- line 21
(x:xs) get 0 = x
(x:xs) get (n+1) = xs get n

当我尝试加载包含该代码的文件时,ghci会出现这个错误。
Prelude> :load ch6.hs 
[1 of 1] Compiling Main             ( ch6.hs, interpreted )

ch6.hs:21:0: Invalid type signature
Failed, modules loaded: none.

我试图创建一个中缀运算符。

2个回答

12

一开始不应该在get周围加上括号。整个定义的语法看起来有些不对。我猜你想要的是这样的:

get :: [a] -> Int -> a
get (x:xs) 0 = x
get (x:xs) (n+1) = xs `get` n
请注意反引号`get`的使用方式,这是为了在这里将其用作中缀运算符,因为字母数字标识符的规则与运算符不同:运算符由符号组成,默认情况下是中缀的,如果要写成没有参数或使用前缀,则将它们放入括号中。字母数字标识符默认为前缀形式,用反引号包围它们可以让您将其用作中缀运算符。
如果您愿意,也可以在左侧使用反引号,但我觉得那样看起来有点奇怪:
(x:xs) `get` 0 = x
(x:xs) `get` (n+1) = xs `get` n

顺便提一下,模式语法n+1已被弃用,所以你可能不应该使用它。相反,应该这样做:

(x:xs) `get` n = xs `get` (n - 1)

2
@Kevin:这适用于运算符,即由符号组成的标识符。对于字母数字标识符,语法是不同的。 - C. A. McCann
2
不仅已被弃用:它在原始的GHC中也无法工作(并且不在Haskell 2010中)。 - ehird
1
@ehird:“它不再工作”仅仅是积极弃用扩散的一个节点。:] - C. A. McCann
@Kevin:哦,嗯,看起来在最新的 GHC(7.2.2)中仍然默认启用。我可能记错了。但它们肯定不在最新的标准中。 - ehird
1
@ehird 已经在 HEAD 中更新,似乎忘记将更改合并到 7.2 分支中。 - Daniel Fischer
显示剩余5条评论

2

仅仅因为你把它放在括号里并不意味着它是一个中缀函数。中缀函数只能通过符号或反引号来创建。具体细节请参见Haskell报告


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接