Online Book Reader

Home Category

Learn You a Haskell for Great Good! - Miran Lipovaca [164]

By Root 522 0
any more breadcrumbs, which meant that we were already at the root of the tree. This is the goUp function that throws an error if we don’t keep within the bounds of our tree:

goUp :: Zipper a -> Zipper a

goUp (t, LeftCrumb x r:bs) = (Node x t r, bs)

goUp (t, RightCrumb x l:bs) = (Node x l t, bs)

Let’s modify it to fail gracefully:

goUp :: Zipper a -> Maybe (Zipper a)

goUp (t, LeftCrumb x r:bs) = Just (Node x t r, bs)

goUp (t, RightCrumb x l:bs) = Just (Node x l t, bs)

goUp (_, []) = Nothing

If we have breadcrumbs, everything is okay, and we return a successful new focus. If we don’t have breadcrumbs, we return a failure.

Before, these functions took zippers and returned zippers, which meant that we could chain them like this to walk around:

gchi> let newFocus = (freeTree, []) -: goLeft -: goRight

But now, instead of returning Zipper a, they return Maybe (Zipper a), and chaining functions like this won’t work. We had a similar problem when we were dealing with our tightrope walker in Chapter 13. He also walked one step at a time, and each of his steps could result in failure, because a bunch of birds could land on one side of his balancing pole and make him fall.

Now the joke is on us, because we’re the ones doing the walking, and we’re traversing a labyrinth of our own devising. Luckily, we can learn from the tightrope walker and just do what he did: replace normal function application with >>=. This takes a value with a context (in our case, the Maybe (Zipper a), which has a context of possible failure) and feeds it into a function, while making sure that the context is handled. So just like our tightrope walker, we’re going to trade in all our -: operators for >>= operators. Then we will be able to chain our functions again! Watch how it works:

ghci> let coolTree = Node 1 Empty (Node 3 Empty Empty)

ghci> return (coolTree, []) >>= goRight

Just (Node 3 Empty Empty,[RightCrumb 1 Empty])

ghci> return (coolTree, []) >>= goRight >>= goRight

Just (Empty,[RightCrumb 3 Empty,RightCrumb 1 Empty])

ghci> return (coolTree, []) >>= goRight >>= goRight >>= goRight

Nothing

We used return to put a zipper in a Just, and then used >>= to feed that to our goRight function. First, we made a tree that has on its left an empty subtree and on its right a node that has two empty subtrees. When we try to go right once, the result is a success, because the operation makes sense. Going right twice is okay, too. We end up with the focus on an empty subtree. But going right three times doesn’t make sense—we can’t go to the right of an empty subtree. This is why the result is a Nothing.

Now we’ve equipped our trees with a safety net that will catch us should we fall off. (Wow, I nailed that metaphor.)

Note

Our filesystem also has a lot of cases where an operation could fail, such as trying to focus on a file or folder that doesn’t exist. As an exercise, you can equip our filesystem with functions that fail gracefully by using the Maybe monad.

Thanks for Reading!

Or just flipping to the last page! I hope you found this book useful and fun. I have strived to give you good insight into the Haskell language and its idioms. While there’s always something new to learn in Haskell, you should now be able to code cool stuff, as well as read and understand other people’s code. So hurry up and get coding! See you on the other side!

Index

A note on the digital index

A link in an index entry is displayed as the section title in which that entry appears. Because some sections have multiple index markers, it is not unusual for an entry to have several links to the same section. Clicking on any link will take you directly to the place in the text in which the marker appears.

Symbols

"\n" (newline) character, adding, Grab the Handles!

(,,) function, using with zip lists, Zip Lists

-> r as functor and monad, Reader? Ugh, Not This Joke Again

-> r, as functor and monad, Reader? Ugh, Not This Joke Again

0 flag, using in Heathrow to London example, Getting a Road System from the Input

3D vector type, implementing, Should We Parameterize

Return Main Page Previous Page Next Page

®Online Book Reader