将我的工作Haskell代码转换为适当的Haskell代码

时间:2014-12-18 16:38:40

标签: haskell

我试图进入哈斯克尔,所以我搞砸了,我写了自己的elem功能,但它看起来很笨重。什么是哈克尔方式来实现这个目标?

elem' x xs = 
    if null xs 
        then False
        else 
            if x == (head xs)
                then True 
                else elem' x (tail xs)  

3 个答案:

答案 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)

首先,如果您使用模式匹配,则可以取出nullheadtail

elem x    []  = False
elem x (y:ys) = ...

仅此一点就可以缩短代码。

(另外,某些人不喜欢headtail,因为如果列表为空,他们会抛出异常。使用上面的模式匹配方法,不存在这样的问题。)

其次,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)