简体   繁体   中英

How does Haskell function `tell` work

I'm learning do expression and Monad using LEARN YOU A HASKELL FOR GREAT GOOD . There's a gcd implementation using tell function makes me confused.

gcd :: Int -> Int -> Writer [String] Int
gcd a b
  | b == 0 = tell ["Finished with " ++ show a ] >>= (\_ -> return a)
  | otherwise = tell [show a ++ " mod " ++ show b ++ " = " ++ show (a `mod` b)] >>= (\_ -> gcd b (a `mod` b))

gcdResult = gcd 8 3

-- result: WriterT (Identity (1,["8 mod 3 = 2","3 mod 2 = 1","2 mod 1 = 0","Finished with 1"]))

But I am confused by the tell function. When using >>= (\\_ -> ...) or >> , the result before will be ignored, so why does the result of tell can be passed to the final result? As my thought, the tell result may be ignored, and the final result will be WriterT (Identity (1,[])) .

You're confusing the result with the context. You are correct that, when applying >> or >>= \\_ -> , the result of the left-hand-side is ignored. However, if the entire value was ignored, it would be completely pointless; the monadic context can be passed forward.

a >> b

This means "take the context from a and combine it with the context of b , keeping the result value of b ". In the case of Writer , the monadic context is that there is some write-only data being passed about.

tell :: Monoid w => w -> Writer w ()

This is the (somewhat simplified) type of tell . It takes a value to write and returns a Writer instance whose result value is insignificant ( () ) but whose context is that there is a write-only value containing the w argument. When you apply >> , the result value is ignored (which is irrelevant because tell returns nothing of value through its result) but the context is kept.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM