我试图进入哈斯克尔,所以我搞砸了,我写了自己的elem功能,但它看起来很笨重。什么是哈克尔方式来实现这个目标?
elem' x xs =
if null xs
then False
else
if x == (head xs)
then True
else elem' x (tail xs)
答案 0 :(得分:8)
您可以使用模式匹配来简化代码
elem' _ [] = False
elem ' x1 (x2:_) | x1 == x2 = True
elem' x (_:ret) = elem' x rest
或者您可以采取完全不同的方法
elem' x = not . null . filter (== x)
(通过懒惰,它不会超过找到的元素,所以你可以elem' 4 [1..]
)
对于那些倾向的人,还有一种折叠方法
elem' x = foldr ((||) . (x==)) False
这也是懒惰的。
答案 1 :(得分:5)
作为手动递归:
elem' :: Eq a => a -> [a] -> Bool
elem' x [] = False
elem' x (y:ys) = x == y || elem' x ys
或使用any
功能:
elem' x xs = any (==x) xs
或
elem' x = any (==x)
甚至
elem' = any . (==)
(虽然我个人并不认为最后一个读得很好)。
答案 2 :(得分:1)
首先,如果您使用模式匹配,则可以取出null
,head
和tail
:
elem x [] = False
elem x (y:ys) = ...
仅此一点就可以缩短代码。
(另外,某些人不喜欢head
和tail
,因为如果列表为空,他们会抛出异常。使用上面的模式匹配方法,不存在这样的问题。)
其次,if foo then True else bar
可以简化为foo || bar
。这是可以的,因为懒惰;如果foo
为真,则永远不会计算bar
(因此在此示例中,递归循环将终止)。
elem x (y:ys) = x == y || elem x ys
其他几个答案也提到你可以使用内置的any
函数,在这种情况下,整个事情变成了一个简单的1-liner:
elem x = any (== x)