通过列表搜索
我一直在试图定义一个函数,给定一个整数和一个整数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
once :: (Eq a) => [a] -> a -> Bool
once xs x = (== 1) $ length $ filter (== x) xs
好了,你可以过滤列表,然后看看有多少元素在得到的滤波器,对不对?
为了让你开始:
> filter (== 2) [1,2,3,4,5]
[2]
> filter (== 2) [1,2,3,4,5,2,2]
[2,2,2]
和你的列表中上下折叠成一个布尔值,在这里,在这里我们测试如果列表中有三个元素的例子,返回一个布尔值:
> isThree (a:b:c:[]) = True
> isThree _ = False
所以它是构成这种功能只有很短的事情:
> isThree . filter (==2)
或您的变种(如匹配对于长度为1的列表)。
我知道,但我只是不知道如何输出到布尔值而不是列出匹配的内容。 – John 2011-04-08 21:34:32
比较列表的长度与1? – 2011-04-08 21:48:59
Once :: [a] - > a - > Bool filter(k)[a] If 1 John 2011-04-08 21:54:39
这里是另一个版本:
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的出现了多次的情况下终止。
,因为我以为我以前的解决方案是丑陋的,我问another forum和得到这个作为答案:
once :: Eq a => a -> [a] -> Bool
once x = (== [x]) . filter (== x)
我认为你不能写一个函数更漂亮,并在对比接受的答案是懒。
感谢您的任何想法如何处理无限的列表? – John 2011-04-08 23:16:00
约翰,你需要在列表中匹配它的长度,而不是像下面的答案那样取长度。 – 2011-04-09 02:23:17
我不认为在一般情况下可以处理无限列表。如何知道确定性程序停止在'repeat 2'中寻找'1'? – acfoltzer 2011-04-09 02:34:06