问题描述
istEnthalten:: a -> [a] -> Bool
istEnthalten elem [] = False
istEnthalten elem (x:xs) = if elem == x
then True
else istEnthalten elem xs
我知道这是可行的:
istEnthalten :: a -> [a] -> Bool
istEnthalten elem [] = False
istEnthalten elem (x:xs)
| elem == x = True
| otherwise = contains elem xs
但是第一个错了吗?
解决方法
istEnthalten :: a -> [a] -> Bool
是一个函数的签名,该函数能够在 any 类型的列表中找到元素。即它甚至可以让您做这样的事情:
collatz :: Integer -> Integer
main = print $ collatz `istEnhalten` [const 1]
那可能行不通。 Integer -> Integer
函数不能不能进行相等比较。
istEnthalten
函数必须被限制为可以进行相等比较的类型,即签名必须是
istEnthalten :: Eq a => a -> [a] -> Bool
有了该签名,您的两次尝试都可以成功。请注意
-
elem
已经是执行您要在此处实现的全部功能的标准函数的名称。因此,尽管在技术上是可行的,但应避免使用elem
作为变量名(您的名称 shadows 是函数中的标准名称)。 -
False
作为一个if
分支会不必要地使事情复杂化。使用布尔运算符可以更好地表达您的逻辑:istEnthalten e (x:xs) = e==x || istEnthalten e xs
(类似地,永远没有充分的理由写
a==True
,这与a
一样。)
True
中的这是我要执行的任务:
infix 4 ∈
(∈) :: Eq a => a -> [a] -> Bool
_ ∈ [] = False
a ∈ x:xs = a==x || a∈xs