【发布时间】:2019-07-19 09:56:52
【问题描述】:
我写了一个过滤函数:
f :: (a -> Bool) -> [a] -> [a]
f p xs = case xs of
[] -> []
x : xs' -> if p x
then x : f p xs'
else f p xs'
为了理解绑定,我想使用绑定来实现它。 我在想什么:
f p xs = xs >>= (\x xs -> if p x then x : f p xs else f p xs)
但我收到此错误:
* Couldn't match expected type `[a]' with actual type `[a] -> [a]'
* The lambda expression `\ x xs -> ...' has two arguments,
but its type `a -> [a]' has only one
In the second argument of `(>>=)', namely
`(\ x xs -> if p x then x : f p xs else f p xs)'
In the expression:
xs >>= (\ x xs -> if p x then x : f p xs else f p xs)
* Relevant bindings include
xs :: [a] (bound at <interactive>:104:5)
p :: a -> Bool (bound at <interactive>:104:3)
f :: (a -> Bool) -> [a] -> [a] (bound at <interactive>:104:1)
使用foldr成功做到了:
f p xs = foldr (\x xs -> if p x then x : f p xs else f p xs) [] xs
怎么了?
【问题讨论】:
-
这不是
do块,所以这里没有使用绑定。 -
列表绑定
>>=是concatMap,而不是foldr。