所以我试图在Haskell中定义一个函数,如果给定一个整数和一个整数列表,它将给出一个真正的'或者' false'整数是否只出现一次。
到目前为止,我已经:
let once :: Eq a => a - > [a] - > BOOL;一旦x l =
但我还没有写完代码。我可以告诉你,我对Haskell很新。
答案 0 :(得分:6)
使用模式匹配开始:
once x [] =
once x (y:ys) =
这不会立即给你一个好的程序,但它会引导你朝着正确的方向前进。
答案 1 :(得分:1)
这是一个不明确使用模式匹配的解决方案。相反,它会跟踪Bool
,表示是否已找到发生。
正如其他人所指出的,这可能是一个家庭作业问题,因此我故意将then
和else
分支留空。我鼓励user3482534尝试使用此代码并自行填充。
once :: Eq a => a -> [a] -> Bool
once a = foldr f False
where f x b = if x == a then ??? else ???
编辑:我原先想到的天真实现是:
once :: Eq a => a -> [a] -> Bool
once a = foldr f False
where f x b = if x == a then b /= True else b
但这不正确,
λ. once 'x' "xxx"
True
当然,False
'x'
应该只发生一次。
但是,为了表明可以使用折叠编写once
,这里是一个修订版本,它使用自定义的monoid来跟踪元素发生的次数:
import Data.List
import Data.Foldable
import Data.Monoid
data Occur = Zero | Once | Many
deriving Eq
instance Monoid Occur where
mempty = Zero
Zero `mappend` x = x
x `mappend` Zero = x
_ `mappend` _ = Many
once :: Eq a => a -> [a] -> Bool
once a = (==) Once . foldMap f
where f x = if x == a then Once else Zero
main = do
let xss = inits "xxxxx"
print $ map (once 'x') xss
打印
[False,True,False,False,False]
正如所料。
once
的结构与原始结构相似但不完全相同。
答案 2 :(得分:0)
我会回答这个问题,好像这是一个家庭作业问题,因为它看起来像是一个。
阅读函数声明中的模式匹配,特别是当它们给出处理列表的示例时。您稍后会使用Data.List中的工具,但您的教授可能正在教授模式匹配。
答案 3 :(得分:0)
考虑将值映射到1或0的函数,具体取决于匹配...
match :: a -> [a] -> [Int]
match x xs = map -- fill in the thing here such that
-- match 3 [1,2,3,4,5] == [0,0,1,0,0]
请注意,sum
函数采用数字列表并返回列表中数字的总和。因此,要计算匹配项,函数可以使用match
函数并返回计数。
countN :: a -> [a] -> Int
countN x xs = ? $ match x xs
最后一个功能利用countN
函数检查只有1的计数。(==1)
。
希望你能弄明白其余的......
答案 4 :(得分:0)
您可以过滤列表,然后检查结果列表的长度。如果length == 1,则只有一次给定的Integer:
once :: Eq a => a -> [a] -> Bool
once x = (== 1) . length . filter (== x)
答案 5 :(得分:0)
通常使用import Data.List (foldl')
进行计数,无点
count pred = foldl' (\ n x -> if pred x then n + 1 else n) 0
适用于
count (< 10) [1 .. 10] == 9
count (== 'l') "Hello" == 2
给出
once pred xs = count pred xs == 1
高效的O(n)短路谓词形式,测试谓词是否只满足一次:
once :: (a -> Bool) -> [a] -> Bool
once pred list = one list 0
where
one [] 1 = True
one [] _ = False
one _ 2 = False
one (x : xs) n | pred x = one xs (n + 1)
| otherwise = one xs n
或者,使用any
:
none pred = not . any pred
once :: (a -> Bool) -> [a] -> Bool
once _ [] = False
once pred (x : xs) | pred x = none pred xs
| otherwise = one pred xs
给出
elemOnce y = once (== y)
其中
elemOnce 47 [1,1,2] == False
elemOnce 2 [1,1,2] == True
elemOnce 81 [81,81,2] == False