无法演绎(Eq i)字面上的'0'

时间:2017-02-17 18:04:47

标签: haskell

我对Haskell很新,并且尝试编写类似于take的函数,即从指定列表返回指定数量的项。我的代码如下:

take' :: (Num i, Ord a) => i -> [a] -> [a]
take' 0 _ = []
take' _ [] = []
take' n (x:xs) = x : take' (n - 1) xs

但是,当我尝试编译它时,我收到以下错误:

Could not deduce (Eq i) arising from the literal ‘0’
from the context (Num i, Ord a)
  bound by the type signature for
             take' :: (Num i, Ord a) => i -> [a] -> [a]
  at recursion.hs:1:10-42
Possible fix:
  add (Eq i) to the context of
    the type signature for take' :: (Num i, Ord a) => i -> [a] -> [a]
In the pattern: 0
In an equation for ‘take'’: take' 0 _ = []

我认为错误是由于Haskell无法识别0作为类类型Num的成员,但我不确定。任何人都可以向我解释错误,并告诉我如何解决它。

1 个答案:

答案 0 :(得分:8)

模式匹配文字数字desugar到相等检查。所以

take' 0 _ = []

变为

take' x _ | x == 0 = []

(其中x被选为该子句中其他地方未提及的变量。因此,为了支持这种模式,您需要的数量不仅仅是Num,还需要支持(==)!这就是错误的这一部分:

Could not deduce (Eq i) arising from the literal ‘0’
In the pattern: 0
In an equation for ‘take'’: take' 0 _ = []

您可以采取GHC在错误中建议的修复:

Possible fix:
  add (Eq i) to the context of
    the type signature for take' :: (Num i, Ord a) => i -> [a] -> [a]

因此:

take' :: (Eq i, Num i, Ord a) => i -> [a] -> [a]

之后您可以考虑是否需要Ord a约束。 =)