搜索列表

时间:2011-04-08 20:58:26

标签: list haskell integer boolean

我一直在尝试定义一个函数,给定一个整数列表和一个整数n,返回一个布尔值,指示n是否恰好在列表中出现一次。

我有这个,但它不起作用,我无法弄清楚

once :: [a] -> (a -> Bool) -> Bool 
filter _ [] = []  
filter p (x:xs)   
    | p x       = x : filter p xs  
    | otherwise = filter p xs 

An example of what I want would be:
Main>  once [2,3,2,4] 2
False
Main> once [1..100] 2
True

4 个答案:

答案 0 :(得分:6)

我认为我以前的解决方案很难看,我在another forum询问并得到了答案:

once :: Eq a => a -> [a] -> Bool
once x = (== [x]) . filter (== x)

我认为你不能更好地编写这个功能,与接受的答案相比,它是懒惰的。

答案 1 :(得分:2)

那么,您可以过滤列表,然后查看生成的过滤器中有多少元素,对吧?

为了帮助您入门:

 > filter (== 2) [1,2,3,4,5]
 [2]

 > filter (== 2) [1,2,3,4,5,2,2]
 [2,2,2]

将列表折叠为Bool值,这里是一个示例,我们测试列表是否有三个元素,返回一个Bool:

 > isThree (a:b:c:[]) = True
 > isThree _          = False 

因此,撰写此类函数只是一个短暂的问题:

 > isThree . filter (==2)

或您的变体(例如,匹配长度为1的列表)。

答案 2 :(得分:2)

once :: (Eq a) => [a] -> a -> Bool
once xs x = (== 1) $ length $ filter (== x) xs

答案 3 :(得分:0)

这是另一个版本:

once x = not . (\xs -> null xs || x `elem` tail xs) . dropWhile (/= x)

--lambda hater version
import Control.Applicative
once x = not . ((||) <$> null <*> (elem x).tail) . dropWhile (/= x)

当然它不能处理包含零或一个x的无限列表,但至少它会在x出现多次的情况下终止。