vam*_*olu 3 haskell literals type-signature
我正在关注Learn you a Haskell for great good,我已经实施了take':
take' :: (Ord i, Num i) => i -> [a] -> [a]
take' n _
| n <= 0 = []
take' _ [] = []
take' n (x:xs) = x: take' (n-1) xs
Run Code Online (Sandbox Code Playgroud)
测试功能时:
take' -2 [2]
Run Code Online (Sandbox Code Playgroud)
而不是得到一个空列表,我有这样的消息:
Non type-variable argument in the constraint: Num (i -> [a] -> [a])
(Use FlexibleContexts to permit this)
When checking that ‘it’ has the inferred type
it :: forall i a t.
(Num i, Num t, Num (i -> [a] -> [a]), Num ([t] -> i -> [a] -> [a]),
Ord i) =>
i -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)
我按照建议在-和之间添加了一个空格2,它导致了同样的错误:
*Main> take' - 2 [2]
<interactive>:78:1:
Non type-variable argument in the constraint: Num (i -> [a] -> [a])
(Use FlexibleContexts to permit this)
When checking that ‘it’ has the inferred type
it :: forall i a t.
(Num i, Num t, Num (i -> [a] -> [a]), Num ([t] -> i -> [a] -> [a]),
Ord i) =>
i -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)
正如评论中已经讨论过的,这只是解析规则的问题。你的表情take' -2 [2]看起来应该是take' (-2) [2]你想要的。可以说,它应该被解析为这样。事实上,GHC 有一个扩展来实现这种行为:
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> :set -XNegativeLiterals
Prelude> take -2 [2]
[]
Run Code Online (Sandbox Code Playgroud)
然而,默认情况下,Haskell 总是首先尝试将所有运算符(包括 )解析-为中缀运算符。在上面的表达式中,-左边和右边都有东西(尽管间距不一致,但被忽略了),所以没有-XNegativeLiteralsthis 最终会被解析为(take) - (2 [2]),这意味着完全不同的东西。真的这完全是假的,正如错误消息以一种非常神秘的方式暗示的那样:它想要Num (i -> [a] -> [a]),即它发现您的代码需要将函数(即,take)视为数字(即,作为减法运算符的参数)。
几乎总是当您看到包括需求在内的错误时Num (Some Compound Type),意味着在解析级别已经完全错误。