I am learning about the filterM function in the book "Learn You a Haskell for Great Good!" by Miran Lipovaca. For the following example:
keepSmall :: Int -> Writer [String] Bool
keepSmall x
| x < 4 = do
tell ["Keeping " ++ show x]
return True
| otherwise = do
tell [show x ++ " is too large, throwing it away"]
return False
The result obtained from using this function with filterM is the following:
> runWriter $ filterM keepSmall [9,1,5,2,10,3]
([1,2,3],["9 is too large, throwing it away","Keeping 1","5 is too large,
throwing it away","Keeping 2","10 is too large, throwing it away","Keeping 3"])
Regarding the type of the result of filterM, I know that filterM has the following type declaration:
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
Since the monad used for this example is Writer [String], would the type of the list resulting from filterM be Writer [String] [Int]? If this is the case, is this why the result type is ([Int], [String]), since Writer w a is equivalent to the tuple (a,w)?
That's because of the type of runWriter
runWriter :: Writer w a -> (a, w)
from Hoogle, it literally just unwrap a writer computation as a (result, output) pair. That's why you got the result in a pair.
A little example, just to see how it works in other context:
runWriter (tell $ return "Hello" ())
=> ((),"Hello")
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