Haskell递归计数

时间:2014-12-06 16:22:24

标签: haskell recursion count

我刚刚开始学习Haskell(我试图制作一个策划者解决方案)。

我必须计算列表中一种颜色出现在另一个列表中的次数:

reaction [Green, Purple, Green, Green] [Purple, Green, Blue, Yellow] 0

必须给我结果" 2",因为" Green"从列表1开始,在列表2中出现1次,对于"紫色"同样如此。所以我写了一小段代码:

reaction [] ys n = n
reaction (x:xs) ys n = foldr (\y _ -> if x == y then reaction (filter' x xs) ys n + 1 else reaction xs ys n + 0) n ys

filter' c xs = filter(\x -> x /= c) xs

它从列表1中获取头部X并将其与列表2中的每个元素进行比较,如果它相同,它将过滤列表1中与X相对应的所有值(因此它不会计算任何值重复)并将+ 1添加到" N"。然而它给了我结果" 1",我真的无法找出原因......我希望有人能帮助我! 史蒂芬

2 个答案:

答案 0 :(得分:1)

首先,filter'只是filter (/= x)

根据您对问题的描述,更清晰的方式(至少最初)是

reaction [] ys n = n
reaction (x : xs) ys n | x `elem` ys = reaction (filter (/= x) xs) ys (n+1)
                       | otherwise = reaction xs ys n

这对我来说似乎不是一个简单的折叠,因为你迭代的列表(xs)会随着你的迭代而改变。

答案 1 :(得分:1)

在你的代码中,你丢弃传递给foldr的函数的第二个参数( accumulator ):

foldr (\y _ -> ...

我想不出foldr的用例,你想要那样做。

你的问题似乎源于对foldr的误解。你确定你明白这个功能是做什么的吗?如果您有任何疑问,请阅读this section of the Wikipedia page on folds;你应该找到解释正确折叠特别有启发性的图表。

如果我正确理解你想做什么,下面的方法应该可以做到:

import Data.List

data Color = Blue | Green | Purple | Yellow
  deriving Eq

reaction :: Eq a => [a] -> [a] -> Int -> Int
reaction xs ys n = foldr (\x acc -> length (filter (== x) ys) + acc) n $ nub xs

有关信息,nub函数采用列表并返回通过从中删除所有重复元素而形成的列表;它由Data.List module导出。

在GHCi中进行测试:

λ> reaction [Green, Purple, Green, Green] [Purple, Green, Blue, Yellow] 0
2