Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding the filterM function

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)?

like image 830
ceno980 Avatar asked Jan 27 '26 22:01

ceno980


1 Answers

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")
like image 154
A Monad is a Monoid Avatar answered Jan 29 '26 11:01

A Monad is a Monoid



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!