Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Haskell function `tell` work

Tags:

haskell

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,[])).

like image 920
wind2412 Avatar asked Aug 16 '17 05:08

wind2412


People also ask

How are functions defined in Haskell?

The most basic way of defining a function in Haskell is to ``declare'' what it does. For example, we can write: double :: Int -> Int double n = 2*n. Here, the first line specifies the type of the function and the second line tells us how the output of double depends on its input.

How does where work in Haskell?

Definition on Haskell Where Function. Haskell where is not a function rather it is a keyword that is used to divide the more complex logic or calculation into smaller parts, which makes the logic or calculation easy to understand and handle.

How does return work in Haskell?

return is actually just a simple function in Haskell. It does not return something. It wraps a value into a monad. Looks like return is an overloaded function.


1 Answers

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.

like image 186
Silvio Mayolo Avatar answered Oct 30 '22 17:10

Silvio Mayolo