Haskell是会员功能错误

Kie*_*ins 6 haskell functional-programming list

isMember:: a -> [a] -> Bool
isMember y [] = False
isMember y (x:xs) =
 if y == x then
  True
 else
  isMember y xs
Run Code Online (Sandbox Code Playgroud)

尝试创建一个函数来识别某些东西是否是列表的成员.例如:

isMember 6 [1,2,3,4,5,6]
>True
Run Code Online (Sandbox Code Playgroud)

但是我一直得到一个编译器错误,声明'因使用'=='而导致的(Eq a)没有实例

帮助将不胜感激(我是函数语言中的Haskell&Recursion的新手,所以解释为我五岁.)

eps*_*lbe 8

你快到了

isMember :: Eq a => a -> [a] -> Bool
isMember _ [] = False
isMember y (x:xs) =
 if y == x then True else isMember y xs
Run Code Online (Sandbox Code Playgroud)

编译器告诉您,您承诺接受任何类型的列表成员 - 但稍后您使用的函数==不适用于所有类型(例如函数).

通过添加Eq a =>你说我接受所有具有等于方法的输入.

一些额外的说明

您可以(重新)将最后一行写为

isMember y (x:xs) = (y == x) || isMember y xs
Run Code Online (Sandbox Code Playgroud)

这相当于你的实现(感谢@chi的评论).你的版本有什么好处,它是尾递归的.

另一点需要注意 - 模式:

  • 为空列表返回一些内容(isMember _ [] = False)
  • 并使用此值迭代列表(isMember y (x:xs) = ...)

碰巧发生了很多事情,并被抽象为fold功能家族(foldl,foldr...).把它放在你的用例中就好了

isMember y xs = foldl False (\x b -> (x == y) || b) xs
Run Code Online (Sandbox Code Playgroud)

  • 既然`||'是懒惰的,我会考虑在所有方面但是语法,尾递归的替代方案.它的执行基本上与尾递归的空间和时间相同. (2认同)