4
\$\begingroup\$

Learn You a Haskell presents an excellent introduction to >>= with an example.

Basically, Pierre is a tight-rope walker that has Birds (Int) on each side of his tight-rope (represented by a tuple (Int, Int)). Birds can land on each side (only one side at a time) with addRight and addLeft. If the difference of birds on left and right is > 4, then Pierre falls.

LYAH says to use the Error Monad:

As an exercise, you can rewrite that with the error monad so that when the tightrope walker slips and falls, we remember how many birds were on each side of the pole when he fell.

Here's how I implemented it (but LYAH provided the type synonyms):

-- @author: LYAH
type Birds = Int
type Pole = (Birds, Birds)

addLeft :: Birds -> Pole -> Either Pole Pole
addLeft n (x, y) = let newLeft = x + n
                       newPole = (newLeft, y)
                       diff    = abs (newLeft - y)
                   in if (diff > 4) then Left  newPole
                      else               Right newPole

addRight :: Birds -> Pole -> Either Pole Pole
addRight n (x, y) = let newRight = y + n
                        newPole = (x, newRight)
                        diff    = abs (x - newRight)
                    in if (diff > 4) then Left  newPole
                       else               Right newPole                       

walkTightRope :: Either Pole Pole
walkTightRope = addLeft 2 (0,0) >>= addRight 4

walkTightRopeFailed :: Either Pole Pole
walkTightRopeFailed = addLeft 2 (0,0) >>= addRight 10 >>= addLeft 2

walkTightRopeDo :: Either Pole Pole
walkTightRopeDo = do 
    p1 <- addLeft 2 (0,0)   
    p2 <- addRight 1 p1
    return p2

Please critique my implementation.

\$\endgroup\$
1
\$\begingroup\$

I don't see glaring flaws. A couple notes though:

-You could combine the addLeft/Right functions and pass in a tuple representing how many birds you want to add ( (0,2) for 2 right ); the functions are almost identical.

-I've found where bindings to read neater if I have more then 2 (personal choice).

-AFAIK, the Error Monad /= the Either Monad.

|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.