我正在进行一项练习,我能想到的唯一解决方案是使用列表来过滤另一个列表。
练习如下:
使用组合
、(.)
、sum
和map
定义一个函数filter
,给定一个值钱包(表示为包含标题名称和金额的对列表)计算其值对于给定的引用(表示为包含标题名称及其值的对列表)。 例如:walletValue :: [(String,Double)] -> [(String,Double)] -> Double
quote= [("apple", 116), ("intel", 35), ("google", 824), ("nvidia", 67)]
>walletValue [("intel", 1), ("nvidia", 1)] quote
102.0
>walletValue [("intel", 3), ("nvidia", 2)] quote
239.0
>walletValue [("intel", 3), ("facebook", 4), ("nvidia", 2)] quote
239.0
我找到了一个解决方案,但没有用
map
和 filter
实现组合。
我的解决方案:
walletValue:: [(String,Double)] -> [(String,Double)] -> Double
walletValue xs ys = sum.concat.(map (\(k,v)-> map (v*) (searchC k ys))) xs
searchC :: Eq a => a -> [(a,b)] -> [b]
searchC k xs = [ v | (k,v) <- xs,k==k']
您的
searchC
充当过滤器,但您没有将其写为过滤器。事实上,你可以重写逻辑:
searchC :: Eq a => a -> [(a,b)] -> [b]
searchC k xs = [ v | (k,v) <- xs,k==k']
使用两种模式将映射和过滤器组合起来。
第一个我们可以重写:
[x | x <- xs, f x]
至:
filter (\x -> f x) xs
第二个,如果列表理解的头部不是变量
x
,就像这里重写的情况一样:
[ f x | x <- xs ]
至:
map (\x -> f x) xs