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