In this post, we will examine the do monad haskell...
Monads in Haskell are so useful that they got their own special syntax called do notation. Its principle is still the same: gluing together monadic values in sequence. We're going to take a look at how do notation works and why it's useful.
ghci> Just 3 >>= (\x -> Just "!" >>= (\y -> Just (show x ++ y))) Just "3!"
which is equivalent to the following.
ghci> let x = 3; y = "!" in show x ++ y "3!"
the monadic value is different from the let do value becaue it has monadic value has failure value.
to make the point more claer, here is another code.
foo :: Maybe String foo = Just 3 >>= (\x -> Just "!" >>= (\y -> Just (show x ++ y)))
and to get rid of all the annoying lambdas, haskell gives us the do notation.
foo :: Maybe String foo = do x <- Just 3 y <- Just "!" Just (show x ++ y)
It's important to remember that do expressions are just different syntax for chaining monadic values.(the <- value like the ability to extract the value from the maybe container)..
In a do expression, every line is a monadic value. To inspect its result, we use<-. If we have a Maybe String and we bind it with <- to a variable, that variable will be a String, just like when we used >>= to feed monadic values to lambdas. The last monadic value in a do expression, likeJust (show x ++ y) here, can't be used with <- to bind its result, because that wouldn't make sense if we translated the do expression back to a chain of>>= applications.Rather, its result is the result of the whole glued up monadic value, taking into account the possible failure of any of the previous ones.
let's see more examples.
ghci> Just 9 >>= (\x -> Just (x > 8)) Just True
which is the same as the following.
marySue :: Maybe Bool marySue = do x <- Just 9 Just (x > 8)
and we can rewrite hte routine that we do land birds.
routine :: Maybe Pole routine = case Just (0,0) of Nothing -> Nothing Just start -> case landLeft 2 start of Nothing -> Nothing Just first -> case landRight 2 first of Nothing -> Nothing Just second -> landLeft 1 second
and that can be write as follow.
routine :: Maybe Pole routine = do start <- return (0,0) first <- landLeft 2 start Nothing second <- landRight 2 first landLeft 1 second
and in do notation, wehen we biknd monadic valus to names, we can utllized pattern matching. just like in let expression functions paramters, here is an example of pattern matching in a do expression,.
justH :: Maybe Char justH = do (x:xs) <- Just "hello" return x
the value returned is 'h'...
the beauty of monad is that it unlike the error binding, which fails and the program might fail, however, with the monad value, you may have a special value to represent a failure value.
remember the definition of hte fail method.
fail :: (Monad m) => String -> m a fail msg = error msg
for maybe, the fail method is define as this.
fail _ = Nothing
so with this, let' see if we feed some error values to it, how it will be reacting to that.
wopwop :: Maybe Char wopwop = do (x:xs) <- Just "" return x
if you run this, and you can see the result as follow.
ghci> wopwop Nothing