I wrote a filter function:
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'
To understand bind, I want to implement this using bind. What I was thinking about:
f p xs = xs >>= (\x xs -> if p x then x : f p xs else f p xs)
But I get this error:
* 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)
Successfully did it using foldr
:
f p xs = foldr (\x xs -> if p x then x : f p xs else f p xs) [] xs
What's going wrong?
To understand bind, i want to implement this as bind.
There is no bind here. The bind is added in case of a do
expression. The above is not a do-expression, so there is no bind here.
You can however write this with bind, like:
f p xs = xs >>= \x -> if p x then [x] else []
but this is not a literal mapping of the original function, we simply make use of the instance Monad []
implementation here. Nevertheless, your f
is just filter :: (a -> Bool) -> [a] -> [a]
here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With