我对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的成员,但我不确定。任何人都可以向我解释错误,并告诉我如何解决它。
答案 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
约束。 =)