haskell - Monads - the do monad

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  

 

你可能感兴趣的:(haskell)