├── .gitignore ├── Makefile ├── README.md ├── UbuntuMono-Regular.otf ├── en ├── 01-introduction.md ├── 02-starting-out.md ├── 03-types-and-typeclasses.md ├── 04-syntax-in-functions.md ├── 05-recursion.md ├── 06-higher-order-functions.md ├── 07-modules.md ├── 08-making-our-own-types-and-typeclasses.md ├── 09-input-and-output.md ├── 10-functionally-solving-problems.md ├── 11-functors-applicative-functors-and-monoids.md ├── 12-a-fistful-of-monads.md ├── 13-for-a-few-monads-more.md └── 14-zippers.md ├── epub-stylesheet.css ├── img ├── 60sdude.png ├── accordion.png ├── alien.png ├── almostzipper.png ├── angeleyes.png ├── arguments.png ├── asstronaut.png ├── baby.png ├── badge.png ├── balloondog.png ├── banana.png ├── bear.png ├── bigtree.png ├── binarytree.png ├── bird.png ├── boat.png ├── bomb.png ├── bonus.png ├── box.png ├── brain.png ├── bread.png ├── buddha.png ├── cactus.png ├── calculator.png ├── case.png ├── caveman.png ├── centaur.png ├── chainchomp.png ├── chess.png ├── chicken.png ├── classes.png ├── clint.png ├── composition.png ├── concatmap.png ├── cool.png ├── cow.png ├── cowboy.png ├── curry.png ├── deadcat.png ├── dognap.png ├── dollar.png ├── edd.png ├── file.png ├── foldl.png ├── frogtor.png ├── functor.png ├── fx.png ├── gob.png ├── guards.png ├── guycar.png ├── helloworld.png ├── jackofdiamonds.png ├── jazzb.png ├── judgedog.png ├── justice.png ├── kermit.png ├── kid.png ├── knight.png ├── krakatoa.png ├── lamb.png ├── lambda.png ├── lazy.png ├── legochar.png ├── legolists.png ├── legomap.png ├── legosets.png ├── letitbe.png ├── lifter.png ├── list.png ├── listmonster.png ├── luggage.png ├── lyah.jpg ├── making_modules.png ├── maoi.png ├── map.png ├── maxs.png ├── meekrat.png ├── miner.png ├── modules.png ├── notes.png ├── origami.png ├── owld.png ├── painter.png ├── pattern.png ├── picard.png ├── pierre.png ├── pirateship.png ├── police.png ├── pollywantsa.png ├── present.png ├── prob.png ├── puppy.png ├── pythag.png ├── quickman.png ├── quicksort.png ├── random.png ├── record.png ├── recursion.png ├── revolver.png ├── ride.png ├── ringring.png ├── roads.png ├── roads_simple.png ├── rpn.png ├── salad.png ├── setnotation.png ├── shamrock.png ├── smug.png ├── smugpig.png ├── spearhead.png ├── spongedisk.png ├── startingout.png ├── streams.png ├── sun.png ├── texas.png ├── thefonz.png ├── timber.png ├── tipi.png ├── trafficlight.png ├── tuco.png ├── tuple.png ├── tur2.png ├── typefoo.png ├── washmachine.png ├── whale.png ├── wolf.png ├── yesno.png └── yeti.png ├── metadata.xml └── title.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.epub 2 | *.pdf 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DOCGEN=pandoc 2 | DOCGEN_FLAGS=--toc 3 | 4 | FILES=01-introduction.md 02-starting-out.md 03-types-and-typeclasses.md 04-syntax-in-functions.md 05-recursion.md 06-higher-order-functions.md 07-modules.md 08-making-our-own-types-and-typeclasses.md 09-input-and-output.md 10-functionally-solving-problems.md 11-functors-applicative-functors-and-monoids.md 12-a-fistful-of-monads.md 13-for-a-few-monads-more.md 14-zippers.md 5 | EPUB_STYLESHEET=epub-stylesheet.css 6 | EPUB_CODE_FONT=UbuntuMono-Regular.otf 7 | 8 | all: epubs pdfs 9 | 10 | epubs: epub-en 11 | -rm -rf en/img/ 12 | 13 | epub-en: copyimg out pandoc metadata.xml 14 | $(DOCGEN) $(DOCGEN_FLAGS) --epub-metadata=metadata.xml --css=$(EPUB_STYLESHEET) --epub-embed-font=$(EPUB_CODE_FONT) -o out/lyah-en.epub --epub-cover-image=img/lyah.jpg title.txt $(addprefix en/, $(FILES)) 15 | 16 | pdfs: pdf-en 17 | 18 | pdf-en: out en pandoc pdflatex 19 | $(DOCGEN) $(DOCGEN_FLAGS) -o out/lyah-en.pdf title.txt $(addprefix en/, $(FILES)) 20 | 21 | copyimg: 22 | -cp -rf img/ en/ 23 | 24 | out: 25 | mkdir out 26 | 27 | pandoc: 28 | @which pandoc > /dev/null 29 | 30 | pdflatex: 31 | @which pdflatex > /dev/null 32 | 33 | clean: 34 | rm -rf out 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Learn You a _Haskell_ for Great Good! 2 | ===================================== 3 | 4 | _by Miran Lipovača._ 5 | 6 | This is my personal copy of “Learn You a Haskell for Great Good!”, the prettiest 7 | book for learning Haskell that I know of. I obtained this copy by using 8 | [Pandoc](http://johnmacfarlane.net/pandoc/). 9 | 10 | You can read the book [online](http://learnyouahaskell.com/chapters) or [buy a 11 | copy](http://nostarch.com/lyah.htm). 12 | 13 | Description at learnyouahaskell.com 14 | ----------------------------------- 15 | 16 | > Hey yo! This is Learn You a Haskell, the funkiest way to learn Haskell, which 17 | > is the best functional programming language around. You may have heard of it. 18 | > This guide is meant for people who have programmed already, but have yet to 19 | > try functional programming. 20 | > 21 | > The whole thing is completely free to read online, but it's also available in 22 | > print and I encourage you to buy as many copies as you can afford! 23 | 24 | > To contact me, shoot me an email to: bonus at learnyouahaskell dot com! You 25 | > can also find me idling on [#haskell](irc://irc.freenode.net/haskell) where I 26 | > go by the name BONUS. 27 | 28 | What is this repo for? 29 | ---------------------- 30 | 31 | With the help of this repo, you can make your own ebook version of the book. 32 | Make sure you have Pandoc installed and pdflatex (for making the pdf) and then 33 | use 'make all', 'make epubs' or 'make pdfs' depending on what you want. 34 | The output will be written to a directory called 'out' 35 | 36 | License 37 | ------- 38 | 39 | This book is licensed under an [Attribution-NonCommercial-ShareAlike 3.0 40 | Unported (CC BY-NC-SA 3.0)](http://creativecommons.org/licenses/by-nc-sa/3.0/) 41 | license. 42 | -------------------------------------------------------------------------------- /UbuntuMono-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/UbuntuMono-Regular.otf -------------------------------------------------------------------------------- /en/01-introduction.md: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | About this tutorial 5 | ------------------- 6 | 7 | Welcome to *Learn You a Haskell for Great Good*! If you're reading this, 8 | chances are you want to learn Haskell. Well, you've come to the right 9 | place, but let's talk about this tutorial a bit first. 10 | 11 | I decided to write this because I wanted to solidify my own knowledge of 12 | Haskell and because I thought I could help people new to Haskell learn 13 | it from my perspective. There are quite a few tutorials on Haskell 14 | floating around on the internet. When I was starting out in Haskell, I 15 | didn't learn from just one resource. The way I learned it was by reading 16 | several different tutorials and articles because each explained 17 | something in a different way than the other did. By going through 18 | several resources, I was able put together the pieces and it all just 19 | came falling into place. So this is an attempt at adding another useful 20 | resource for learning Haskell so you have a bigger chance of finding one 21 | you like. 22 | 23 | ![bird](img/bird.png) 24 | 25 | This tutorial is aimed at people who have experience in imperative 26 | programming languages (C, C++, Java, Python …) but haven't programmed in 27 | a functional language before (Haskell, ML, OCaml …). Although I bet that 28 | even if you don't have any significant programming experience, a smart 29 | person such as yourself will be able to follow along and learn Haskell. 30 | 31 | The channel \#haskell on the freenode network is a great place to ask 32 | questions if you're feeling stuck. People there are extremely nice, 33 | patient and understanding to newbies. 34 | 35 | I failed to learn Haskell approximately 2 times before finally grasping 36 | it because it all just seemed too weird to me and I didn't get it. But 37 | then once it just "clicked" and after getting over that initial hurdle, 38 | it was pretty much smooth sailing. I guess what I'm trying to say is: 39 | Haskell is great and if you're interested in programming you should 40 | really learn it even if it seems weird at first. Learning Haskell is 41 | much like learning to program for the first time — it's fun! It forces 42 | you to think differently, which brings us to the next section … 43 | 44 | So what's Haskell? 45 | ------------------ 46 | 47 | ![fx](img/fx.png) Haskell is a *purely 48 | functional programming language*. In imperative languages you get things 49 | done by giving the computer a sequence of tasks and then it executes 50 | them. While executing them, it can change state. For instance, you set 51 | variable `a` to 5 and then do some stuff and then set it to something 52 | else. You have control flow structures for doing some action several 53 | times. In purely functional programming you don't tell the computer what 54 | to do as such but rather you tell it what stuff *is*. The factorial of a 55 | number is the product of all the numbers from 1 to that number, the sum 56 | of a list of numbers is the first number plus the sum of all the other 57 | numbers, and so on. You express that in the form of functions. You also 58 | can't set a variable to something and then set it to something else 59 | later. If you say that a is 5, you can't say it's something else later 60 | because you just said it was 5. What are you, some kind of liar? So in 61 | purely functional languages, a function has no side-effects. The only 62 | thing a function can do is calculate something and return it as a 63 | result. At first, this seems kind of limiting but it actually has some 64 | very nice consequences: if a function is called twice with the same 65 | parameters, it's guaranteed to return the same result. That's called 66 | referential transparency and not only does it allow the compiler to 67 | reason about the program's behavior, but it also allows you to easily 68 | deduce (and even prove) that a function is correct and then build more 69 | complex functions by gluing simple functions together. 70 | 71 | ![lazy](img/lazy.png) Haskell is *lazy*. That 72 | means that unless specifically told otherwise, Haskell won't execute 73 | functions and calculate things until it's really forced to show you a 74 | result. That goes well with referential transparency and it allows you 75 | to think of programs as a series of *transformations on data*. It also 76 | allows cool things such as infinite data structures. Say you have an 77 | immutable list of numbers `xs = [1,2,3,4,5,6,7,8]` and a function `doubleMe` 78 | which multiplies every element by 2 and then returns a new list. If we 79 | wanted to multiply our list by 8 in an imperative language and did 80 | `doubleMe(doubleMe(doubleMe(xs)))`, it would probably pass through the 81 | list once and make a copy and then return it. Then it would pass through 82 | the list another two times and return the result. In a lazy language, 83 | calling `doubleMe` on a list without forcing it to show you the result 84 | ends up in the program sort of telling you "Yeah yeah, I'll do it 85 | later!". But once you want to see the result, the first `doubleMe` tells 86 | the second one it wants the result, now! The second one says that to the 87 | third one and the third one reluctantly gives back a doubled 1, which is 88 | a 2. The second one receives that and gives back 4 to the first one. The 89 | first one sees that and tells you the first element is 8. So it only 90 | does one pass through the list and only when you really need it. That 91 | way when you want something from a lazy language you can just take some 92 | initial data and efficiently transform and mend it so it resembles what 93 | you want at the end. 94 | 95 | ![boat](img/boat.png) Haskell is *statically 96 | typed*. When you compile your program, the compiler knows which piece of 97 | code is a number, which is a string and so on. That means that a lot of 98 | possible errors are caught at compile time. If you try to add together a 99 | number and a string, the compiler will whine at you. Haskell uses a very 100 | good type system that has *type inference*. That means that you don't 101 | have to explicitly label every piece of code with a type because the 102 | type system can intelligently figure out a lot about it. If you say `a = 103 | 5 + 4`, you don't have to tell Haskell that `a` is a number, it can figure 104 | that out by itself. Type inference also allows your code to be more 105 | general. If a function you make takes two parameters and adds them 106 | together and you don't explicitly state their type, the function will 107 | work on any two parameters that act like numbers. 108 | 109 | Haskell is *elegant and concise*. Because it uses a lot of high level 110 | concepts, Haskell programs are usually shorter than their imperative 111 | equivalents. And shorter programs are easier to maintain than longer 112 | ones and have less bugs. 113 | 114 | Haskell was made by some *really smart guys* (with PhDs). Work on 115 | Haskell began in 1987 when a committee of researchers got together to 116 | design a kick-ass language. In 2003 the Haskell Report was published, 117 | which defines a stable version of the language. 118 | 119 | What you need to dive in 120 | ------------------------ 121 | 122 | A text editor and a Haskell compiler. You probably already have your 123 | favorite text editor installed so we won't waste time on that. For the 124 | purposes of this tutorial we'll be using GHC, the most widely used 125 | Haskell compiler. The best way to get started is to download the 126 | [Haskell Platform](http://hackage.haskell.org/platform/), which is 127 | basically Haskell with batteries included. 128 | 129 | GHC can take a Haskell script (they usually have a .hs extension) and 130 | compile it but it also has an interactive mode which allows you to 131 | interactively interact with scripts. Interactively. You can call 132 | functions from scripts that you load and the results are displayed 133 | immediately. For learning it's a lot easier and faster than compiling 134 | every time you make a change and then running the program from the 135 | prompt. The interactive mode is invoked by typing in `ghci` at your 136 | prompt. If you have defined some functions in a file called, say, 137 | `myfunctions.hs`, you load up those functions by typing in `:l myfunctions` 138 | and then you can play with them, provided `myfunctions.hs` is in the same 139 | folder from which `ghci` was invoked. If you change the .hs script, just 140 | run `:l myfunctions` again or do `:r`, which is equivalent because it 141 | reloads the current script. The usual workflow for me when playing 142 | around in stuff is defining some functions in a .hs file, loading it up 143 | and messing around with them and then changing the .hs file, loading it 144 | up again and so on. This is also what we'll be doing here. 145 | -------------------------------------------------------------------------------- /en/02-starting-out.md: -------------------------------------------------------------------------------- 1 | Starting Out 2 | ============ 3 | 4 | Ready, set, go! 5 | --------------- 6 | 7 | ![egg](img/startingout.png) Alright, let's get 8 | started! If you're the sort of horrible person who doesn't read 9 | introductions to things and you skipped it, you might want to read the 10 | last section in the introduction anyway because it explains what you 11 | need to follow this tutorial and how we're going to load functions. The 12 | first thing we're going to do is run ghc's interactive mode and call 13 | some function to get a very basic feel for haskell. Open your terminal 14 | and type in `ghci`. You will be greeted with something like this. 15 | 16 | ~~~~ {.haskell: .ghci name="code"} 17 | GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help 18 | Loading package base ... linking ... done. 19 | Prelude> 20 | ~~~~ 21 | 22 | Congratulations, you're in GHCI! The prompt here is `Prelude>` but 23 | because it can get longer when you load stuff into the session, we're 24 | going to use `ghci>`. If you want to have the same prompt, just type in 25 | `:set prompt "ghci> "`. 26 | 27 | Here's some simple arithmetic. 28 | 29 | ~~~~ {.haskell: .ghci name="code"} 30 | ghci> 2 + 15 31 | 17 32 | ghci> 49 * 100 33 | 4900 34 | ghci> 1892 - 1472 35 | 420 36 | ghci> 5 / 2 37 | 2.5 38 | ghci> 39 | ~~~~ 40 | 41 | This is pretty self-explanatory. We can also use several operators on 42 | one line and all the usual precedence rules are obeyed. We can use 43 | parentheses to make the precedence explicit or to change it. 44 | 45 | ~~~~ {.haskell: .ghci name="code"} 46 | ghci> (50 * 100) - 4999 47 | 1 48 | ghci> 50 * 100 - 4999 49 | 1 50 | ghci> 50 * (100 - 4999) 51 | -244950 52 | ~~~~ 53 | 54 | Pretty cool, huh? Yeah, I know it's not but bear with me. A little 55 | pitfall to watch out for here is negating numbers. If we want to have a 56 | negative number, it's always best to surround it with parentheses. Doing 57 | `5 * -3` will make GHCI yell at you but doing `5 * (-3)` will work just 58 | fine. 59 | 60 | Boolean algebra is also pretty straightforward. As you probably know, `&&` 61 | means a boolean *and*, `||` means a boolean *or*. `not` negates a `True` or a 62 | `False`. 63 | 64 | ~~~~ {.haskell: .ghci name="code"} 65 | ghci> True && False 66 | False 67 | ghci> True && True 68 | True 69 | ghci> False || True 70 | True 71 | ghci> not False 72 | True 73 | ghci> not (True && True) 74 | False 75 | ~~~~ 76 | 77 | Testing for equality is done like so. 78 | 79 | ~~~~ {.haskell: .ghci name="code"} 80 | ghci> 5 == 5 81 | True 82 | ghci> 1 == 0 83 | False 84 | ghci> 5 /= 5 85 | False 86 | ghci> 5 /= 4 87 | True 88 | ghci> "hello" == "hello" 89 | True 90 | ~~~~ 91 | 92 | What about doing `5 + "llama"` or `5 == True`? Well, if we try the first 93 | snippet, we get a big scary error message! 94 | 95 | ~~~~ {.haskell: .ghci name="code"} 96 | No instance for (Num [Char]) 97 | arising from a use of `+' at :1:0-9 98 | Possible fix: add an instance declaration for (Num [Char]) 99 | In the expression: 5 + "llama" 100 | In the definition of `it': it = 5 + "llama" 101 | ~~~~ 102 | 103 | Yikes! What GHCI is telling us here is that `"llama"` is not a number and 104 | so it doesn't know how to add it to 5. Even if it wasn't `"llama"` but 105 | `"four"` or `"4"`, Haskell still wouldn't consider it to be a number. `+` 106 | expects its left and right side to be numbers. If we tried to do `True == 5`, 107 | GHCI would tell us that the types don't match. Whereas `+` works only 108 | on things that are considered numbers, `==` works on any two things that 109 | can be compared. But the catch is that they both have to be the same 110 | type of thing. You can't compare apples and oranges. We'll take a closer 111 | look at types a bit later. Note: you can do `5 + 4.0` because `5` is sneaky 112 | and can act like an integer or a floating-point number. `4.0` can't act 113 | like an integer, so `5` is the one that has to adapt. 114 | 115 | You may not have known it but we've been using functions now all along. 116 | For instance, `*` is a function that takes two numbers and multiplies 117 | them. As you've seen, we call it by sandwiching it between them. This is 118 | what we call an *infix* function. Most functions that aren't used with 119 | numbers are *prefix* functions. Let's take a look at them. 120 | 121 | ![phoen](img/ringring.png) Functions are 122 | usually prefix so from now on we won't explicitly state that a function 123 | is of the prefix form, we'll just assume it. In most imperative 124 | languages functions are called by writing the function name and then 125 | writing its parameters in parentheses, usually separated by commas. In 126 | Haskell, functions are called by writing the function name, a space and 127 | then the parameters, separated by spaces. For a start, we'll try calling 128 | one of the most boring functions in Haskell. 129 | 130 | ~~~~ {.haskell: .ghci name="code"} 131 | ghci> succ 8 132 | 9 133 | ~~~~ 134 | 135 | The `succ` function takes anything that has a defined successor and 136 | returns that successor. As you can see, we just separate the function 137 | name from the parameter with a space. Calling a function with several 138 | parameters is also simple. The functions `min` and `max` take two things 139 | that can be put in an order (like numbers!). `min` returns the one that's 140 | lesser and `max` returns the one that's greater. See for yourself: 141 | 142 | ~~~~ {.haskell: .ghci name="code"} 143 | ghci> min 9 10 144 | 9 145 | ghci> min 3.4 3.2 146 | 3.2 147 | ghci> max 100 101 148 | 101 149 | ~~~~ 150 | 151 | Function application (calling a function by putting a space after it and 152 | then typing out the parameters) has the highest precedence of them all. 153 | What that means for us is that these two statements are equivalent. 154 | 155 | ~~~~ {.haskell: .ghci name="code"} 156 | ghci> succ 9 + max 5 4 + 1 157 | 16 158 | ghci> (succ 9) + (max 5 4) + 1 159 | 16 160 | ~~~~ 161 | 162 | However, if we wanted to get the successor of the product of numbers 9 163 | and 10, we couldn't write `succ 9 * 10` because that would get the 164 | successor of 9, which would then be multiplied by 10. So 100. We'd have 165 | to write `succ (9 * 10)` to get 91. 166 | 167 | If a function takes two parameters, we can also call it as an infix 168 | function by surrounding it with backticks. For instance, the `div` 169 | function takes two integers and does integral division between them. 170 | Doing `div 92 10` results in a 9. But when we call it like that, there may 171 | be some confusion as to which number is doing the division and which one 172 | is being divided. So we can call it as an infix function by doing 173 | ``92 `div` 10`` and suddenly it's much clearer. 174 | 175 | Lots of people who come from imperative languages tend to stick to the 176 | notion that parentheses should denote function application. For example, 177 | in C, you use parentheses to call functions like `foo()`, `bar(1)` or 178 | `baz(3, "haha")`. Like we said, spaces are used for function application in 179 | Haskell. So those functions in Haskell would be `foo`, `bar 1` and `baz 3 180 | "haha"`. So if you see something like `bar (bar 3)`, it doesn't mean that 181 | `bar` is called with `bar` and `3` as parameters. It means that we first call 182 | the function `bar` with `3` as the parameter to get some number and then we 183 | call `bar` again with that number. In C, that would be something like 184 | `bar(bar(3))`. 185 | 186 | Baby's first functions 187 | ---------------------- 188 | 189 | In the previous section we got a basic feel for calling functions. Now 190 | let's try making our own! Open up your favorite text editor and punch in 191 | this function that takes a number and multiplies it by two. 192 | 193 | ~~~~ {.haskell: .hs name="code"} 194 | doubleMe x = x + x 195 | ~~~~ 196 | 197 | Functions are defined in a similar way that they are called. The 198 | function name is followed by parameters separated by spaces. But when 199 | defining functions, there's a `=` and after that we define what the 200 | function does. Save this as `baby.hs` or something. Now navigate to where 201 | it's saved and run `ghci` from there. Once inside GHCI, do `:l baby`. Now 202 | that our script is loaded, we can play with the function that we 203 | defined. 204 | 205 | ~~~~ {.haskell: .ghci name="code"} 206 | ghci> :l baby 207 | [1 of 1] Compiling Main ( baby.hs, interpreted ) 208 | Ok, modules loaded: Main. 209 | ghci> doubleMe 9 210 | 18 211 | ghci> doubleMe 8.3 212 | 16.6 213 | ~~~~ 214 | 215 | Because `+` works on integers as well as on floating-point numbers 216 | (anything that can be considered a number, really), our function also 217 | works on any number. Let's make a function that takes two numbers and 218 | multiplies each by two and then adds them together. 219 | 220 | ~~~~ {.haskell: .hs name="code"} 221 | doubleUs x y = x*2 + y*2 222 | ~~~~ 223 | 224 | Simple. We could have also defined it as `doubleUs x y = x + x + y + y`. 225 | Testing it out produces pretty predictable results (remember to append 226 | this function to the `baby.hs` file, save it and then do `:l baby` inside 227 | GHCI). 228 | 229 | ~~~~ {.haskell: .ghci name="code"} 230 | ghci> doubleUs 4 9 231 | 26 232 | ghci> doubleUs 2.3 34.2 233 | 73.0 234 | ghci> doubleUs 28 88 + doubleMe 123 235 | 478 236 | ~~~~ 237 | 238 | As expected, you can call your own functions from other functions that 239 | you made. With that in mind, we could redefine `doubleUs` like this: 240 | 241 | ~~~~ {.haskell: .hs name="code"} 242 | doubleUs x y = doubleMe x + doubleMe y 243 | ~~~~ 244 | 245 | This is a very simple example of a common pattern you will see 246 | throughout Haskell. Making basic functions that are obviously correct 247 | and then combining them into more complex functions. This way you also 248 | avoid repetition. What if some mathematicians figured out that 2 is 249 | actually 3 and you had to change your program? You could just redefine 250 | `doubleMe` to be `x + x + x` and since `doubleUs` calls `doubleMe`, it would 251 | automatically work in this strange new world where 2 is 3. 252 | 253 | Functions in Haskell don't have to be in any particular order, so it 254 | doesn't matter if you define `doubleMe` first and then `doubleUs` or if you 255 | do it the other way around. 256 | 257 | Now we're going to make a function that multiplies a number by 2 but 258 | only if that number is smaller than or equal to 100 because numbers 259 | bigger than 100 are big enough as it is! 260 | 261 | ~~~~ {.haskell: .hs name="code"} 262 | doubleSmallNumber x = if x > 100 263 | then x 264 | else x*2 265 | ~~~~ 266 | 267 | ![this is you](img/baby.png) 268 | 269 | Right here we introduced Haskell's if statement. You're probably 270 | familiar with if statements from other languages. The difference between 271 | Haskell's if statement and if statements in imperative languages is that 272 | the else part is mandatory in Haskell. In imperative languages you can 273 | just skip a couple of steps if the condition isn't satisfied but in 274 | Haskell every expression and function must return something. We could 275 | have also written that if statement in one line but I find this way more 276 | readable. Another thing about the if statement in Haskell is that it is 277 | an *expression*. An expression is basically a piece of code that returns 278 | a value. `5` is an expression because it returns 5, `4 + 8` is an 279 | expression, `x + y` is an expression because it returns the sum of `x` and 280 | `y`. Because the else is mandatory, an if statement will always return 281 | something and that's why it's an expression. If we wanted to add one to 282 | every number that's produced in our previous function, we could have 283 | written its body like this. 284 | 285 | ~~~~ {.haskell: .hs name="code"} 286 | doubleSmallNumber' x = (if x > 100 then x else x*2) + 1 287 | ~~~~ 288 | 289 | Had we omitted the parentheses, it would have added one only if `x` wasn't 290 | greater than 100. Note the `'` at the end of the function name. That 291 | apostrophe doesn't have any special meaning in Haskell's syntax. It's a 292 | valid character to use in a function name. We usually use `'` to either 293 | denote a strict version of a function (one that isn't lazy) or a 294 | slightly modified version of a function or a variable. Because `'` is a 295 | valid character in functions, we can make a function like this. 296 | 297 | ~~~~ {.haskell: .hs name="code"} 298 | conanO'Brien = "It's a-me, Conan O'Brien!" 299 | ~~~~ 300 | 301 | There are two noteworthy things here. The first is that in the function 302 | name we didn't capitalize Conan's name. That's because functions can't 303 | begin with uppercase letters. We'll see why a bit later. The second 304 | thing is that this function doesn't take any parameters. When a function 305 | doesn't take any parameters, we usually say it's a *definition* (or a 306 | *name*). Because we can't change what names (and functions) mean once 307 | we've defined them, `conanO'Brien` and the string `"It's a-me, Conan 308 | O'Brien!"` can be used interchangeably. 309 | 310 | An intro to lists 311 | ----------------- 312 | 313 | ![BUY A DOG](img/list.png) Much like shopping 314 | lists in the real world, lists in Haskell are very useful. It's the most 315 | used data structure and it can be used in a multitude of different ways 316 | to model and solve a whole bunch of problems. Lists are SO awesome. In 317 | this section we'll look at the basics of lists, strings (which are 318 | lists) and list comprehensions. 319 | 320 | In Haskell, lists are a *homogenous* data structure. It stores several 321 | elements of the same type. That means that we can have a list of 322 | integers or a list of characters but we can't have a list that has a few 323 | integers and then a few characters. And now, a list! 324 | 325 | > *Note*: We can use the `let` keyword to define a name right in GHCI. Doing 326 | > `let a = 1` inside GHCI is the equivalent of writing `a = 1` in a script and 327 | > then loading it. 328 | 329 | ~~~~ {.haskell: .ghci name="code"} 330 | ghci> let lostNumbers = [4,8,15,16,23,42] 331 | ghci> lostNumbers 332 | [4,8,15,16,23,42] 333 | ~~~~ 334 | 335 | As you can see, lists are denoted by square brackets and the values in 336 | the lists are separated by commas. If we tried a list like 337 | `[1,2,'a',3,'b','c',4]`, Haskell would complain that characters (which 338 | are, by the way, denoted as a character between single quotes) are not 339 | numbers. Speaking of characters, strings are just lists of characters. 340 | `"hello"` is just syntactic sugar for `['h','e','l','l','o']`. Because 341 | strings are lists, we can use list functions on them, which is really 342 | handy. 343 | 344 | A common task is putting two lists together. This is done by using the 345 | `++` operator. 346 | 347 | ~~~~ {.haskell: .ghci name="code"} 348 | ghci> [1,2,3,4] ++ [9,10,11,12] 349 | [1,2,3,4,9,10,11,12] 350 | ghci> "hello" ++ " " ++ "world" 351 | "hello world" 352 | ghci> ['w','o'] ++ ['o','t'] 353 | "woot" 354 | ~~~~ 355 | 356 | Watch out when repeatedly using the `++` operator on long strings. When 357 | you put together two lists (even if you append a singleton list to a 358 | list, for instance: `[1,2,3] ++ [4]`), internally, Haskell has to walk 359 | through the whole list on the left side of `++`. That's not a problem when 360 | dealing with lists that aren't too big. But putting something at the end 361 | of a list that's fifty million entries long is going to take a while. 362 | However, putting something at the beginning of a list using the `:` 363 | operator (also called the cons operator) is instantaneous. 364 | 365 | ~~~~ {.haskell: .ghci name="code"} 366 | ghci> 'A':" SMALL CAT" 367 | "A SMALL CAT" 368 | ghci> 5:[1,2,3,4,5] 369 | [5,1,2,3,4,5] 370 | ~~~~ 371 | 372 | Notice how `:` takes a number and a list of numbers or a character and a 373 | list of characters, whereas `++` takes two lists. Even if you're adding an 374 | element to the end of a list with `++`, you have to surround it with 375 | square brackets so it becomes a list. 376 | 377 | `[1,2,3]` is actually just syntactic sugar for `1:2:3:[]`. `[]` is an empty 378 | list. If we prepend `3` to it, it becomes `[3]`. If we prepend `2` to that, it 379 | becomes `[2,3]`, and so on. 380 | 381 | > *Note:* `[]`, `[[]]` and `[[],[],[]]` are all different things. The first one 382 | > is an empty list, the second one is a list that contains one empty list, the 383 | > third one is a list that contains three empty lists. 384 | 385 | If you want to get an element out of a list by index, use `!!`. The 386 | indices start at 0. 387 | 388 | ~~~~ {.haskell: .ghci name="code"} 389 | ghci> "Steve Buscemi" !! 6 390 | 'B' 391 | ghci> [9.4,33.2,96.2,11.2,23.25] !! 1 392 | 33.2 393 | ~~~~ 394 | 395 | But if you try to get the sixth element from a list that only has four 396 | elements, you'll get an error so be careful! 397 | 398 | Lists can also contain lists. They can also contain lists that contain 399 | lists that contain lists … 400 | 401 | ~~~~ {.haskell: .ghci name="code"} 402 | ghci> let b = [[1,2,3,4],[5,3,3,3],[1,2,2,3,4],[1,2,3]] 403 | ghci> b 404 | [[1,2,3,4],[5,3,3,3],[1,2,2,3,4],[1,2,3]] 405 | ghci> b ++ [[1,1,1,1]] 406 | [[1,2,3,4],[5,3,3,3],[1,2,2,3,4],[1,2,3],[1,1,1,1]] 407 | ghci> [6,6,6]:b 408 | [[6,6,6],[1,2,3,4],[5,3,3,3],[1,2,2,3,4],[1,2,3]] 409 | ghci> b !! 2 410 | [1,2,2,3,4] 411 | ~~~~ 412 | 413 | The lists within a list can be of different lengths but they can't be of 414 | different types. Just like you can't have a list that has some 415 | characters and some numbers, you can't have a list that has some lists 416 | of characters and some lists of numbers. 417 | 418 | Lists can be compared if the stuff they contain can be compared. When 419 | using `<`, `<=`, `>` and `>=` to compare lists, they are compared in 420 | lexicographical order. First the heads are compared. If they are equal 421 | then the second elements are compared, etc. 422 | 423 | ~~~~ {.haskell: .ghci name="code"} 424 | ghci> [3,2,1] > [2,1,0] 425 | True 426 | ghci> [3,2,1] > [2,10,100] 427 | True 428 | ghci> [3,4,2] > [3,4] 429 | True 430 | ghci> [3,4,2] > [2,4] 431 | True 432 | ghci> [3,4,2] == [3,4,2] 433 | True 434 | ~~~~ 435 | 436 | What else can you do with lists? Here are some basic functions that 437 | operate on lists. 438 | 439 | `head` takes a list and returns its head. The head of a list is basically 440 | its first element. 441 | 442 | ~~~~ {.haskell: .ghci name="code"} 443 | ghci> head [5,4,3,2,1] 444 | 5 445 | ~~~~ 446 | 447 | `tail` takes a list and returns its tail. In other words, it chops off a 448 | list's head. 449 | 450 | ~~~~ {.haskell: .ghci name="code"} 451 | ghci> tail [5,4,3,2,1] 452 | [4,3,2,1] 453 | ~~~~ 454 | 455 | `last` takes a list and returns its last element. 456 | 457 | ~~~~ {.haskell: .ghci name="code"} 458 | ghci> last [5,4,3,2,1] 459 | 1 460 | ~~~~ 461 | 462 | `init` takes a list and returns everything except its last element. 463 | 464 | ~~~~ {.haskell: .ghci name="code"} 465 | ghci> init [5,4,3,2,1] 466 | [5,4,3,2] 467 | ~~~~ 468 | 469 | If we think of a list as a monster, here's what's what. 470 | 471 | ![list monster](img/listmonster.png) 472 | 473 | But what happens if we try to get the head of an empty list? 474 | 475 | ~~~~ {.haskell: .ghci name="code"} 476 | ghci> head [] 477 | *** Exception: Prelude.head: empty list 478 | ~~~~ 479 | 480 | Oh my! It all blows up in our face! If there's no monster, it doesn't 481 | have a head. When using `head`, `tail`, `last` and `init`, be careful not to use 482 | them on empty lists. This error cannot be caught at compile time so it's 483 | always good practice to take precautions against accidentally telling 484 | Haskell to give you some elements from an empty list. 485 | 486 | `length` takes a list and returns its length, obviously. 487 | 488 | ~~~~ {.haskell: .ghci name="code"} 489 | ghci> length [5,4,3,2,1] 490 | 5 491 | ~~~~ 492 | 493 | `null` checks if a list is empty. If it is, it returns `True`, otherwise it 494 | returns `False`. Use this function instead of `xs == []` (if you have a list 495 | called `xs`) 496 | 497 | ~~~~ {.haskell: .ghci name="code"} 498 | ghci> null [1,2,3] 499 | False 500 | ghci> null [] 501 | True 502 | ~~~~ 503 | 504 | `reverse` reverses a list. 505 | 506 | ~~~~ {.haskell: .ghci name="code"} 507 | ghci> reverse [5,4,3,2,1] 508 | [1,2,3,4,5] 509 | ~~~~ 510 | 511 | `take` takes number and a list. It extracts that many elements from the 512 | beginning of the list. Watch. 513 | 514 | ~~~~ {.haskell: .ghci name="code"} 515 | ghci> take 3 [5,4,3,2,1] 516 | [5,4,3] 517 | ghci> take 1 [3,9,3] 518 | [3] 519 | ghci> take 5 [1,2] 520 | [1,2] 521 | ghci> take 0 [6,6,6] 522 | [] 523 | ~~~~ 524 | 525 | See how if we try to take more elements than there are in the list, it 526 | just returns the list. If we try to take 0 elements, we get an empty 527 | list. 528 | 529 | `drop` works in a similar way, only it drops the number of elements from 530 | the beginning of a list. 531 | 532 | ~~~~ {.haskell: .ghci name="code"} 533 | ghci> drop 3 [8,4,2,1,5,6] 534 | [1,5,6] 535 | ghci> drop 0 [1,2,3,4] 536 | [1,2,3,4] 537 | ghci> drop 100 [1,2,3,4] 538 | [] 539 | ~~~~ 540 | 541 | `maximum` takes a list of stuff that can be put in some kind of order and 542 | returns the biggest element. 543 | 544 | `minimum` returns the smallest. 545 | 546 | ~~~~ {.haskell: .ghci name="code"} 547 | ghci> minimum [8,4,2,1,5,6] 548 | 1 549 | ghci> maximum [1,9,2,3,4] 550 | 9 551 | ~~~~ 552 | 553 | `sum` takes a list of numbers and returns their sum. 554 | 555 | `product` takes a list of numbers and returns their product. 556 | 557 | ~~~~ {.haskell: .ghci name="code"} 558 | ghci> sum [5,2,1,6,3,2,5,7] 559 | 31 560 | ghci> product [6,2,1,2] 561 | 24 562 | ghci> product [1,2,5,6,7,9,2,0] 563 | 0 564 | ~~~~ 565 | 566 | `elem` takes a thing and a list of things and tells us if that thing is an 567 | element of the list. It's usually called as an infix function because 568 | it's easier to read that way. 569 | 570 | ~~~~ {.haskell: .ghci name="code"} 571 | ghci> 4 `elem` [3,4,5,6] 572 | True 573 | ghci> 10 `elem` [3,4,5,6] 574 | False 575 | ~~~~ 576 | 577 | Those were a few basic functions that operate on lists. We'll take a 578 | look at more list functions [later](#data-list) 579 | 580 | Texas ranges 581 | ------------ 582 | 583 | ![draw](img/cowboy.png) What if we want a list 584 | of all numbers between 1 and 20? Sure, we could just type them all out 585 | but obviously that's not a solution for gentlemen who demand excellence 586 | from their programming languages. Instead, we'll use ranges. Ranges are 587 | a way of making lists that are arithmetic sequences of elements that can 588 | be enumerated. Numbers can be enumerated. One, two, three, four, etc. 589 | Characters can also be enumerated. The alphabet is an enumeration of 590 | characters from A to Z. Names can't be enumerated. What comes after 591 | "John"? I don't know. 592 | 593 | To make a list containing all the natural numbers from 1 to 20, you just 594 | write `[1..20]`. That is the equivalent of writing 595 | `[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]` and there's no 596 | difference between writing one or the other except that writing out long 597 | enumeration sequences manually is stupid. 598 | 599 | ~~~~ {.haskell: .ghci name="code"} 600 | ghci> [1..20] 601 | [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 602 | ghci> ['a'..'z'] 603 | "abcdefghijklmnopqrstuvwxyz" 604 | ghci> ['K'..'Z'] 605 | "KLMNOPQRSTUVWXYZ" 606 | ~~~~ 607 | 608 | Ranges are cool because you can also specify a step. What if we want all 609 | even numbers between 1 and 20? Or every third number between 1 and 20? 610 | 611 | ~~~~ {.haskell: .ghci name="code"} 612 | ghci> [2,4..20] 613 | [2,4,6,8,10,12,14,16,18,20] 614 | ghci> [3,6..20] 615 | [3,6,9,12,15,18] 616 | ~~~~ 617 | 618 | It's simply a matter of separating the first two elements with a comma 619 | and then specifying what the upper limit is. While pretty smart, ranges 620 | with steps aren't as smart as some people expect them to be. You can't 621 | do `[1,2,4,8,16..100]` and expect to get all the powers of 2. Firstly 622 | because you can only specify one step. And secondly because some 623 | sequences that aren't arithmetic are ambiguous if given only by a few of 624 | their first terms. 625 | 626 | To make a list with all the numbers from 20 to 1, you can't just do 627 | `[20..1]`, you have to do `[20,19..1]`. 628 | 629 | Watch out when using floating point numbers in ranges! Because they are 630 | not completely precise (by definition), their use in ranges can yield 631 | some pretty funky results. 632 | 633 | ~~~~ {.haskell: .ghci name="code"} 634 | ghci> [0.1, 0.3 .. 1] 635 | [0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999] 636 | ~~~~ 637 | 638 | My advice is not to use them in list ranges. 639 | 640 | You can also use ranges to make infinite lists by just not specifying an 641 | upper limit. Later we'll go into more detail on infinite lists. For now, 642 | let's examine how you would get the first 24 multiples of 13. Sure, you 643 | could do `[13,26..24*13]`. But there's a better way: `take 24 [13,26..]`. 644 | Because Haskell is lazy, it won't try to evaluate the infinite list 645 | immediately because it would never finish. It'll wait to see what you 646 | want to get out of that infinite lists. And here it sees you just want 647 | the first 24 elements and it gladly obliges. 648 | 649 | A handful of functions that produce infinite lists: 650 | 651 | `cycle` takes a list and cycles it into an infinite list. If you just try 652 | to display the result, it will go on forever so you have to slice it off 653 | somewhere. 654 | 655 | ~~~~ {.haskell: .ghci name="code"} 656 | ghci> take 10 (cycle [1,2,3]) 657 | [1,2,3,1,2,3,1,2,3,1] 658 | ghci> take 12 (cycle "LOL ") 659 | "LOL LOL LOL " 660 | ~~~~ 661 | 662 | `repeat` takes an element and produces an infinite list of just that 663 | element. It's like cycling a list with only one element. 664 | 665 | ~~~~ {.haskell: .ghci name="code"} 666 | ghci> take 10 (repeat 5) 667 | [5,5,5,5,5,5,5,5,5,5] 668 | ~~~~ 669 | 670 | Although it's simpler to just use the `replicate` function if you want 671 | some number of the same element in a list. `replicate 3 10` returns 672 | `[10,10,10]`. 673 | 674 | 675 | 676 | I'm a list comprehension 677 | ------------------------ 678 | 679 | ![frog](img/kermit.png) If you've ever taken a 680 | course in mathematics, you've probably run into *set comprehensions*. 681 | They're normally used for building more specific sets out of general 682 | sets. A basic comprehension for a set that contains the first ten even 683 | natural numbers is ![set 684 | notation](img/setnotation.png). The part before 685 | the pipe is called the output function, `x` is the variable, `N` is the 686 | input set and `x <= 10` is the predicate. That means that the set 687 | contains the doubles of all natural numbers that satisfy the predicate. You 688 | would read this as, "The set of all `2x` such that `x` is in the set of all 689 | natural numbers, and `x` is less than or equal to 10." 690 | 691 | If we wanted to write that in Haskell, we could do something like `take 692 | 10 [2,4..]`. But what if we didn't want doubles of the first 10 natural 693 | numbers but some kind of more complex function applied on them? We could 694 | use a list comprehension for that. List comprehensions are very similar 695 | to set comprehensions. We'll stick to getting the first 10 even numbers 696 | for now. The list comprehension we could use is `[x*2 | x <- [1..10]]`. 697 | `x` is drawn from `[1..10]` and for every element in `[1..10]` (which we have 698 | bound to `x`), we get that element, only doubled. Here's that 699 | comprehension in action. 700 | 701 | ~~~~ {.haskell: .ghci name="code"} 702 | ghci> [x*2 | x <- [1..10]] 703 | [2,4,6,8,10,12,14,16,18,20] 704 | ~~~~ 705 | 706 | As you can see, we get the desired results. Now let's add a condition 707 | (or a predicate) to that comprehension. Predicates go after the binding 708 | parts and are separated from them by a comma. Let's say we want only the 709 | elements which, doubled, are greater than or equal to 12. 710 | 711 | ~~~~ {.haskell: .ghci name="code"} 712 | ghci> [x*2 | x <- [1..10], x*2 >= 12] 713 | [12,14,16,18,20] 714 | ~~~~ 715 | 716 | Cool, it works. How about if we wanted all numbers from 50 to 100 whose 717 | remainder when divided with the number 7 is 3? Easy. 718 | 719 | ~~~~ {.haskell: .ghci name="code"} 720 | ghci> [ x | x <- [50..100], x `mod` 7 == 3] 721 | [52,59,66,73,80,87,94] 722 | ~~~~ 723 | 724 | Success! Note that weeding out lists by predicates is also called 725 | *filtering*. We took a list of numbers and we filtered them by the 726 | predicate. Now for another example. Let's say we want a comprehension 727 | that replaces each odd number greater than 10 with `"BANG!"` and each odd 728 | number that's less than 10 with `"BOOM!"`. If a number isn't odd, we throw 729 | it out of our list. For convenience, we'll put that comprehension inside 730 | a function so we can easily reuse it. 731 | 732 | ~~~~ {.haskell: .ghci name="code"} 733 | boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x] 734 | ~~~~ 735 | 736 | The last part of the comprehension is the predicate. The function `odd` 737 | returns `True` on an odd number and `False` on an even one. The element is 738 | included in the list only if all the predicates evaluate to `True`. 739 | 740 | ~~~~ {.haskell: .hs name="code"} 741 | ghci> boomBangs [7..13] 742 | ["BOOM!","BOOM!","BANG!","BANG!"] 743 | ~~~~ 744 | 745 | We can include several predicates. If we wanted all numbers from 10 to 746 | 20 that are not 13, 15 or 19, we'd do: 747 | 748 | ~~~~ {.haskell: .ghci name="code"} 749 | ghci> [ x | x <- [10..20], x /= 13, x /= 15, x /= 19] 750 | [10,11,12,14,16,17,18,20] 751 | ~~~~ 752 | 753 | Not only can we have multiple predicates in list comprehensions (an 754 | element must satisfy all the predicates to be included in the resulting 755 | list), we can also draw from several lists. When drawing from several 756 | lists, comprehensions produce all combinations of the given lists and 757 | then join them by the output function we supply. A list produced by a 758 | comprehension that draws from two lists of length 4 will have a length 759 | of 16, provided we don't filter them. If we have two lists, `[2,5,10]` and 760 | `[8,10,11]` and we want to get the products of all the possible 761 | combinations between numbers in those lists, here's what we'd do. 762 | 763 | ~~~~ {.haskell: .ghci name="code"} 764 | ghci> [ x*y | x <- [2,5,10], y <- [8,10,11]] 765 | [16,20,22,40,50,55,80,100,110] 766 | ~~~~ 767 | 768 | As expected, the length of the new list is 9. What if we wanted all 769 | possible products that are more than 50? 770 | 771 | ~~~~ {.haskell: .ghci name="code"} 772 | ghci> [ x*y | x <- [2,5,10], y <- [8,10,11], x*y > 50] 773 | [55,80,100,110] 774 | ~~~~ 775 | 776 | How about a list comprehension that combines a list of adjectives and a 777 | list of nouns … for epic hilarity. 778 | 779 | ~~~~ {.haskell: .ghci name="code"} 780 | ghci> let nouns = ["hobo","frog","pope"] 781 | ghci> let adjectives = ["lazy","grouchy","scheming"] 782 | ghci> [adjective ++ " " ++ noun | adjective <- adjectives, noun <- nouns] 783 | ["lazy hobo","lazy frog","lazy pope","grouchy hobo","grouchy frog", 784 | "grouchy pope","scheming hobo","scheming frog","scheming pope"] 785 | ~~~~ 786 | 787 | I know! Let's write our own version of `length`! We'll call it `length'`. 788 | 789 | ~~~~ {.haskell: .hs name="code"} 790 | length' xs = sum [1 | _ <- xs] 791 | ~~~~ 792 | 793 | `_` means that we don't care what we'll draw from the list anyway so 794 | instead of writing a variable name that we'll never use, we just write 795 | `_`. This function replaces every element of a list with `1` and then sums 796 | that up. This means that the resulting sum will be the length of our 797 | list. 798 | 799 | Just a friendly reminder: because strings are lists, we can use list 800 | comprehensions to process and produce strings. Here's a function that 801 | takes a string and removes everything except uppercase letters from it. 802 | 803 | ~~~~ {.haskell: .hs name="code"} 804 | removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']] 805 | ~~~~ 806 | 807 | Testing it out: 808 | 809 | ~~~~ {.haskell: .ghci name="code"} 810 | ghci> removeNonUppercase "Hahaha! Ahahaha!" 811 | "HA" 812 | ghci> removeNonUppercase "IdontLIKEFROGS" 813 | "ILIKEFROGS" 814 | ~~~~ 815 | 816 | The predicate here does all the work. It says that the character will be 817 | included in the new list only if it's an element of the list `['A'..'Z']`. 818 | Nested list comprehensions are also possible if you're operating on 819 | lists that contain lists. A list contains several lists of numbers. 820 | Let's remove all odd numbers without flattening the list. 821 | 822 | ~~~~ {.haskell: .ghci name="code"} 823 | ghci> let xxs = [[1,3,5,2,3,1,2,4,5],[1,2,3,4,5,6,7,8,9],[1,2,4,2,1,6,3,1,3,2,3,6]] 824 | ghci> [ [ x | x <- xs, even x ] | xs <- xxs] 825 | [[2,2,4],[2,4,6,8],[2,4,2,6,2,6]] 826 | ~~~~ 827 | 828 | You can write list comprehensions across several lines. So if you're not 829 | in GHCI, it's better to split longer list comprehensions across multiple 830 | lines, especially if they're nested. 831 | 832 | Tuples 833 | ------ 834 | 835 | ![tuples](img/tuple.png) 836 | 837 | In some ways, tuples are like lists — they are a way to store several 838 | values into a single value. However, there are a few fundamental 839 | differences. A list of numbers is a list of numbers. That's its type and 840 | it doesn't matter if it has only one number in it or an infinite amount 841 | of numbers. Tuples, however, are used when you know exactly how many 842 | values you want to combine and its type depends on how many components 843 | it has and the types of the components. They are denoted with 844 | parentheses and their components are separated by commas. 845 | 846 | Another key difference is that they don't have to be homogenous. Unlike 847 | a list, a tuple can contain a combination of several types. 848 | 849 | Think about how we'd represent a two-dimensional vector in Haskell. One 850 | way would be to use a list. That would kind of work. So what if we 851 | wanted to put a couple of vectors in a list to represent points of a 852 | shape on a two-dimensional plane? We could do something like 853 | `[[1,2],[8,11],[4,5]]`. The problem with that method is that we could also 854 | do stuff like `[[1,2],[8,11,5],[4,5]]`, which Haskell has no problem with 855 | since it's still a list of lists with numbers but it kind of doesn't 856 | make sense. But a tuple of size two (also called a pair) is its own 857 | type, which means that a list can't have a couple of pairs in it and 858 | then a triple (a tuple of size three), so let's use that instead. 859 | Instead of surrounding the vectors with square brackets, we use 860 | parentheses: `[(1,2),(8,11),(4,5)]`. What if we tried to make a shape like 861 | `[(1,2),(8,11,5),(4,5)]`? Well, we'd get this error: 862 | 863 | ~~~~ {.haskell: .ghci name="code"} 864 | Couldn't match expected type `(t, t1)' 865 | against inferred type `(t2, t3, t4)' 866 | In the expression: (8, 11, 5) 867 | In the expression: [(1, 2), (8, 11, 5), (4, 5)] 868 | In the definition of `it': it = [(1, 2), (8, 11, 5), (4, 5)] 869 | ~~~~ 870 | 871 | It's telling us that we tried to use a pair and a triple in the same 872 | list, which is not supposed to happen. You also couldn't make a list 873 | like `[(1,2),("One",2)]` because the first element of the list is a pair 874 | of numbers and the second element is a pair consisting of a string and a 875 | number. Tuples can also be used to represent a wide variety of data. For 876 | instance, if we wanted to represent someone's name and age in Haskell, 877 | we could use a triple: `("Christopher", "Walken", 55)`. As seen in this 878 | example, tuples can also contain lists. 879 | 880 | Use tuples when you know in advance how many components some piece of 881 | data should have. Tuples are much more rigid because each different size 882 | of tuple is its own type, so you can't write a general function to 883 | append an element to a tuple — you'd have to write a function for 884 | appending to a pair, one function for appending to a triple, one 885 | function for appending to a 4-tuple, etc. 886 | 887 | While there are singleton lists, there's no such thing as a singleton 888 | tuple. It doesn't really make much sense when you think about it. A 889 | singleton tuple would just be the value it contains and as such would 890 | have no benefit to us. 891 | 892 | Like lists, tuples can be compared with each other if their components 893 | can be compared. Only you can't compare two tuples of different sizes, 894 | whereas you can compare two lists of different sizes. Two useful 895 | functions that operate on pairs: 896 | 897 | `fst` takes a pair and returns its first component. 898 | 899 | ~~~~ {.haskell: .ghci name="code"} 900 | ghci> fst (8,11) 901 | 8 902 | ghci> fst ("Wow", False) 903 | "Wow" 904 | ~~~~ 905 | 906 | `snd` takes a pair and returns its second component. Surprise! 907 | 908 | ~~~~ {.haskell: .ghci name="code"} 909 | ghci> snd (8,11) 910 | 11 911 | ghci> snd ("Wow", False) 912 | False 913 | ~~~~ 914 | 915 | > *Note:* these functions operate only on pairs. They won't work on 916 | > triples, 4-tuples, 5-tuples, etc. We'll go over extracting data from 917 | > tuples in different ways a bit later. 918 | 919 | A cool function that produces a list of pairs: `zip`. It takes two lists 920 | and then zips them together into one list by joining the matching 921 | elements into pairs. It's a really simple function but it has loads of 922 | uses. It's especially useful for when you want to combine two lists in a 923 | way or traverse two lists simultaneously. Here's a demonstration. 924 | 925 | ~~~~ {.haskell: .ghci name="code"} 926 | ghci> zip [1,2,3,4,5] [5,5,5,5,5] 927 | [(1,5),(2,5),(3,5),(4,5),(5,5)] 928 | ghci> zip [1 .. 5] ["one", "two", "three", "four", "five"] 929 | [(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five")] 930 | ~~~~ 931 | 932 | It pairs up the elements and produces a new list. The first element goes 933 | with the first, the second with the second, etc. Notice that because 934 | pairs can have different types in them, `zip` can take two lists that 935 | contain different types and zip them up. What happens if the lengths of 936 | the lists don't match? 937 | 938 | ~~~~ {.haskell: .ghci name="code"} 939 | ghci> zip [5,3,2,6,2,7,2,5,4,6,6] ["im","a","turtle"] 940 | [(5,"im"),(3,"a"),(2,"turtle")] 941 | ~~~~ 942 | 943 | The longer list simply gets cut off to match the length of the shorter 944 | one. Because Haskell is lazy, we can zip finite lists with infinite 945 | lists: 946 | 947 | ~~~~ {.haskell: .ghci name="code"} 948 | ghci> zip [1..] ["apple", "orange", "cherry", "mango"] 949 | [(1,"apple"),(2,"orange"),(3,"cherry"),(4,"mango")] 950 | ~~~~ 951 | 952 | ![look at meee](img/pythag.png) 953 | 954 | Here's a problem that combines tuples and list comprehensions: which 955 | right triangle that has integers for all sides and all sides equal to or 956 | smaller than 10 has a perimeter of 24? First, let's try generating all 957 | triangles with sides equal to or smaller than 10: 958 | 959 | ~~~~ {.haskell: .ghci name="code"} 960 | ghci> let triangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10] ] 961 | ~~~~ 962 | 963 | We're just drawing from three lists and our output function is combining 964 | them into a triple. If you evaluate that by typing out `triangles` in 965 | GHCI, you'll get a list of all possible triangles with sides under or 966 | equal to 10. Next, we'll add a condition that they all have to be right 967 | triangles. We'll also modify this function by taking into consideration 968 | that side b isn't larger than the hypotenuse and that side a isn't 969 | larger than side b. 970 | 971 | ~~~~ {.haskell: .ghci name="code"} 972 | ghci> let rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2] 973 | ~~~~ 974 | 975 | We're almost done. Now, we just modify the function by saying that we 976 | want the ones where the perimeter is 24. 977 | 978 | ~~~~ {.haskell: .ghci name="code"} 979 | ghci> let rightTriangles' = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, a+b+c == 24] 980 | ghci> rightTriangles' 981 | [(6,8,10)] 982 | ~~~~ 983 | 984 | And there's our answer! This is a common pattern in functional 985 | programming. You take a starting set of solutions and then you apply 986 | transformations to those solutions and filter them until you get the 987 | right ones. 988 | -------------------------------------------------------------------------------- /en/03-types-and-typeclasses.md: -------------------------------------------------------------------------------- 1 | Types and Typeclasses 2 | ===================== 3 | 4 | Believe the type 5 | ---------------- 6 | 7 | ![moo](img/cow.png) 8 | 9 | Previously we mentioned that Haskell has a static type system. The type 10 | of every expression is known at compile time, which leads to safer code. 11 | If you write a program where you try to divide a boolean type with some 12 | number, it won't even compile. That's good because it's better to catch 13 | such errors at compile time instead of having your program crash. 14 | Everything in Haskell has a type, so the compiler can reason quite a lot 15 | about your program before compiling it. 16 | 17 | Unlike Java or Pascal, Haskell has type inference. If we write a number, 18 | we don't have to tell Haskell it's a number. It can *infer* that on its 19 | own, so we don't have to explicitly write out the types of our functions 20 | and expressions to get things done. We covered some of the basics of 21 | Haskell with only a very superficial glance at types. However, 22 | understanding the type system is a very important part of learning 23 | Haskell. 24 | 25 | A type is a kind of label that every expression has. It tells us in 26 | which category of things that expression fits. The expression `True` is a 27 | boolean, `"hello"` is a string, etc. 28 | 29 | Now we'll use GHCI to examine the types of some expressions. We'll do 30 | that by using the `:t` command which, followed by any valid expression, 31 | tells us its type. Let's give it a whirl. 32 | 33 | ~~~~ {.haskell: .ghci name="code"} 34 | ghci> :t 'a' 35 | 'a' :: Char 36 | ghci> :t True 37 | True :: Bool 38 | ghci> :t "HELLO!" 39 | "HELLO!" :: [Char] 40 | ghci> :t (True, 'a') 41 | (True, 'a') :: (Bool, Char) 42 | ghci> :t 4 == 5 43 | 4 == 5 :: Bool 44 | ~~~~ 45 | 46 | ![bomb](img/bomb.png) Here we see that doing `:t` 47 | on an expression prints out the expression followed by `::` and its type. 48 | `::` is read as "has type of". Explicit types are always denoted with the 49 | first letter in capital case. `'a'`, as it would seem, has a type of `Char`. 50 | It's not hard to conclude that it stands for *character*. `True` is of a 51 | `Bool` type. That makes sense. But what's this? Examining the type of 52 | `"HELLO!"` yields a `[Char]`. The square brackets denote a list. So we read 53 | that as it being *a list of characters*. Unlike lists, each tuple length 54 | has its own type. So the expression of `(True, 'a')` has a type of 55 | `(Bool, Char)`, whereas an expression such as `('a','b','c')` would have the 56 | type of `(Char, Char, Char)`. `4 == 5` will always return `False`, so its type 57 | is `Bool`. 58 | 59 | Functions also have types. When writing our own functions, we can choose 60 | to give them an explicit type declaration. This is generally considered 61 | to be good practice except when writing very short functions. From here 62 | on, we'll give all the functions that we make type declarations. 63 | Remember the list comprehension we made previously that filters a string 64 | so that only caps remain? Here's how it looks like with a type 65 | declaration. 66 | 67 | ~~~~ {.haskell: .hs name="code"} 68 | removeNonUppercase :: [Char] -> [Char] 69 | removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']] 70 | ~~~~ 71 | 72 | `removeNonUppercase` has a type of `[Char] -> [Char]`, meaning that it maps 73 | from a string to a string. That's because it takes one string as a 74 | parameter and returns another as a result. The `[Char]` type is synonymous 75 | with `String` so it's clearer if we write 76 | `removeNonUppercase :: String -> String`. 77 | We didn't have to give this function a type declaration because 78 | the compiler can infer by itself that it's a function from a string to a 79 | string but we did anyway. But how do we write out the type of a function 80 | that takes several parameters? Here's a simple function that takes three 81 | integers and adds them together: 82 | 83 | ~~~~ {.haskell: .hs name="code"} 84 | addThree :: Int -> Int -> Int -> Int 85 | addThree x y z = x + y + z 86 | ~~~~ 87 | 88 | The parameters are separated with `->` and there's no special distinction 89 | between the parameters and the return type. The return type is the last 90 | item in the declaration and the parameters are the first three. Later on 91 | we'll see why they're all just separated with `->` instead of having some 92 | more explicit distinction between the return types and the parameters 93 | like `Int, Int, Int -> Int` or something. 94 | 95 | If you want to give your function a type declaration but are unsure as 96 | to what it should be, you can always just write the function without it 97 | and then check it with `:t`. Functions are expressions too, so `:t` works 98 | on them without a problem. 99 | 100 | Here's an overview of some common types. 101 | 102 | `Int` stands for integer. It's used for whole numbers. `7` can be an `Int` but 103 | `7.2` cannot. `Int` is bounded, which means that it has a minimum and a 104 | maximum value. Usually on 32-bit machines the maximum possible `Int` is 105 | 2147483647 and the minimum is -2147483648. 106 | 107 | `Integer` stands for, er … also integer. The main difference is that it's 108 | not bounded so it can be used to represent really really big numbers. I 109 | mean like really big. `Int`, however, is more efficient. 110 | 111 | ~~~~ {.haskell: .hs name="code"} 112 | factorial :: Integer -> Integer 113 | factorial n = product [1..n] 114 | ~~~~ 115 | 116 | ~~~~ {.haskell: .ghci name="code"} 117 | ghci> factorial 50 118 | 30414093201713378043612608166064768844377641568960512000000000000 119 | ~~~~ 120 | 121 | `Float` is a real floating point with single precision. 122 | 123 | ~~~~ {.haskell: .hs name="code"} 124 | circumference :: Float -> Float 125 | circumference r = 2 * pi * r 126 | ~~~~ 127 | 128 | ~~~~ {.haskell: .ghci name="code"} 129 | ghci> circumference 4.0 130 | 25.132742 131 | ~~~~ 132 | 133 | `Double` is a real floating point with double the precision! 134 | 135 | ~~~~ {.haskell: .hs name="code"} 136 | circumference' :: Double -> Double 137 | circumference' r = 2 * pi * r 138 | ~~~~ 139 | 140 | ~~~~ {.haskell: .ghci name="code"} 141 | ghci> circumference' 4.0 142 | 25.132741228718345 143 | ~~~~ 144 | 145 | `Bool` is a boolean type. It can have only two values: `True` and `False`. 146 | 147 | `Char` represents a character. It's denoted by single quotes. A list of 148 | characters is a string. 149 | 150 | Tuples are types but they are dependent on their length as well as the 151 | types of their components, so there is theoretically an infinite number 152 | of tuple types, which is too many to cover in this tutorial. Note that 153 | the empty tuple `()` is also a type which can only have a single value: `()` 154 | 155 | Type variables 156 | -------------- 157 | 158 | What do you think is the type of the `head` function? Because `head` takes a 159 | list of any type and returns the first element, so what could it be? 160 | Let's check! 161 | 162 | ~~~~ {.haskell: .ghci name="code"} 163 | ghci> :t head 164 | head :: [a] -> a 165 | ~~~~ 166 | 167 | ![box](img/box.png) Hmmm! What is this `a`? Is it 168 | a type? Remember that we previously stated that types are written in 169 | capital case, so it can't exactly be a type. Because it's not in capital 170 | case it's actually a *type variable*. That means that `a` can be of any 171 | type. This is much like generics in other languages, only in Haskell 172 | it's much more powerful because it allows us to easily write very 173 | general functions if they don't use any specific behavior of the types 174 | in them. Functions that have type variables are called *polymorphic 175 | functions*. The type declaration of `head` states that it takes a list of 176 | any type and returns one element of that type. 177 | 178 | Although type variables can have names longer than one character, we 179 | usually give them names of a, b, c, d … 180 | 181 | Remember `fst`? It returns the first component of a pair. Let's examine 182 | its type. 183 | 184 | ~~~~ {.haskell: .ghci name="code"} 185 | ghci> :t fst 186 | fst :: (a, b) -> a 187 | ~~~~ 188 | 189 | We see that `fst` takes a tuple which contains two types and returns an 190 | element which is of the same type as the pair's first component. That's 191 | why we can use `fst` on a pair that contains any two types. Note that just 192 | because `a` and `b` are different type variables, they don't have to be 193 | different types. It just states that the first component's type and the 194 | return value's type are the same. 195 | 196 | 197 | 198 | Typeclasses 101 199 | --------------- 200 | 201 | ![class](img/classes.png) 202 | 203 | A typeclass is a sort of interface that defines some behavior. If a type 204 | is a part of a typeclass, that means that it supports and implements the 205 | behavior the typeclass describes. A lot of people coming from OOP get 206 | confused by typeclasses because they think they are like classes in 207 | object oriented languages. Well, they're not. You can think of them kind 208 | of as Java interfaces, only better. 209 | 210 | What's the type signature of the `==` function? 211 | 212 | ~~~~ {.haskell: .ghci name="code"} 213 | ghci> :t (==) 214 | (==) :: (Eq a) => a -> a -> Bool 215 | ~~~~ 216 | 217 | > *Note*: the equality operator, `==` is a function. So are `+`, `*`, `-`, `/` and 218 | > pretty much all operators. If a function is comprised only of special 219 | > characters, it's considered an infix function by default. If we want to 220 | > examine its type, pass it to another function or call it as a prefix 221 | > function, we have to surround it in parentheses. 222 | 223 | Interesting. We see a new thing here, the `=>` symbol. Everything before 224 | the `=>` symbol is called a *class constraint*. We can read the previous 225 | type declaration like this: the equality function takes any two values 226 | that are of the same type and returns a `Bool`. The type of those two 227 | values must be a member of the `Eq` class (this was the class constraint). 228 | 229 | The `Eq` typeclass provides an interface for testing for equality. Any 230 | type where it makes sense to test for equality between two values of 231 | that type should be a member of the `Eq` class. All standard Haskell types 232 | except for `IO` (the type for dealing with input and output) and functions 233 | are a part of the `Eq` typeclass. 234 | 235 | The `elem` function has a type of `(Eq a) => a -> [a] -> Bool` because it 236 | uses `==` over a list to check whether some value we're looking for is in 237 | it. 238 | 239 | Some basic typeclasses: 240 | 241 | `Eq` is used for types that support equality testing. The functions its 242 | members implement are `==` and `/=`. So if there's an `Eq` class constraint 243 | for a type variable in a function, it uses `==` or `/=` somewhere inside its 244 | definition. All the types we mentioned previously except for functions 245 | are part of `Eq`, so they can be tested for equality. 246 | 247 | ~~~~ {.haskell: .ghci name="code"} 248 | ghci> 5 == 5 249 | True 250 | ghci> 5 /= 5 251 | False 252 | ghci> 'a' == 'a' 253 | True 254 | ghci> "Ho Ho" == "Ho Ho" 255 | True 256 | ghci> 3.432 == 3.432 257 | True 258 | ~~~~ 259 | 260 | `Ord` is for types that have an ordering. 261 | 262 | ~~~~ {.haskell: .ghci name="code"} 263 | ghci> :t (>) 264 | (>) :: (Ord a) => a -> a -> Bool 265 | ~~~~ 266 | 267 | All the types we covered so far except for functions are part of `Ord`. 268 | `Ord` covers all the standard comparing functions such as `>`, `<`, `>=` and 269 | `<=`. The `compare` function takes two `Ord` members of the same type and 270 | returns an ordering. `Ordering` is a type that can be `GT`, `LT` or `EQ`, 271 | meaning *greater than*, *lesser than* and *equal*, respectively. 272 | 273 | To be a member of `Ord`, a type must first have membership in the 274 | prestigious and exclusive `Eq` club. 275 | 276 | ~~~~ {.haskell: .ghci name="code"} 277 | ghci> "Abrakadabra" < "Zebra" 278 | True 279 | ghci> "Abrakadabra" `compare` "Zebra" 280 | LT 281 | ghci> 5 >= 2 282 | True 283 | ghci> 5 `compare` 3 284 | GT 285 | ~~~~ 286 | 287 | Members of `Show` can be presented as strings. All types covered so far 288 | except for functions are a part of `Show`. The most used function that 289 | deals with the `Show` typeclass is show. It takes a value whose type is a 290 | member of `Show` and presents it to us as a string. 291 | 292 | ~~~~ {.haskell: .ghci name="code"} 293 | ghci> show 3 294 | "3" 295 | ghci> show 5.334 296 | "5.334" 297 | ghci> show True 298 | "True" 299 | ~~~~ 300 | 301 | `Read` is sort of the opposite typeclass of `Show`. The `read` function takes 302 | a string and returns a type which is a member of `Read`. 303 | 304 | ~~~~ {.haskell: .ghci name="code"} 305 | ghci> read "True" || False 306 | True 307 | ghci> read "8.2" + 3.8 308 | 12.0 309 | ghci> read "5" - 2 310 | 3 311 | ghci> read "[1,2,3,4]" ++ [3] 312 | [1,2,3,4,3] 313 | ~~~~ 314 | 315 | So far so good. Again, all types covered so far are in this typeclass. 316 | But what happens if we try to do just `read "4"`? 317 | 318 | ~~~~ {.haskell: .ghci name="code"} 319 | ghci> read "4" 320 | :1:0: 321 | Ambiguous type variable `a' in the constraint: 322 | `Read a' arising from a use of `read' at :1:0-7 323 | Probable fix: add a type signature that fixes these type variable(s) 324 | ~~~~ 325 | 326 | What GHCI is telling us here is that it doesn't know what we want in 327 | return. Notice that in the previous uses of `read` we did something with 328 | the result afterwards. That way, GHCI could infer what kind of result we 329 | wanted out of our `read`. If we used it as a boolean, it knew it had to 330 | return a `Bool`. But now, it knows we want some type that is part of the 331 | `Read` class, it just doesn't know which one. Let's take a look at the 332 | type signature of `read`. 333 | 334 | ~~~~ {.haskell: .ghci name="code"} 335 | ghci> :t read 336 | read :: (Read a) => String -> a 337 | ~~~~ 338 | 339 | See? It returns a type that's part of `Read` but if we don't try to use it 340 | in some way later, it has no way of knowing which type. That's why we 341 | can use explicit *type annotations*. Type annotations are a way of 342 | explicitly saying what the type of an expression should be. We do that 343 | by adding `::` at the end of the expression and then specifying a type. 344 | Observe: 345 | 346 | ~~~~ {.haskell: .ghci name="code"} 347 | ghci> read "5" :: Int 348 | 5 349 | ghci> read "5" :: Float 350 | 5.0 351 | ghci> (read "5" :: Float) * 4 352 | 20.0 353 | ghci> read "[1,2,3,4]" :: [Int] 354 | [1,2,3,4] 355 | ghci> read "(3, 'a')" :: (Int, Char) 356 | (3, 'a') 357 | ~~~~ 358 | 359 | Most expressions are such that the compiler can infer what their type is 360 | by itself. But sometimes, the compiler doesn't know whether to return a 361 | value of type `Int` or `Float` for an expression like `read "5"`. To see what 362 | the type is, Haskell would have to actually evaluate `read "5"`. But since 363 | Haskell is a statically typed language, it has to know all the types 364 | before the code is compiled (or in the case of GHCI, evaluated). So we 365 | have to tell Haskell: "Hey, this expression should have this type, in 366 | case you don't know!". 367 | 368 | `Enum` members are sequentially ordered types — they can be enumerated. 369 | The main advantage of the `Enum` typeclass is that we can use its types in 370 | list ranges. They also have defined successors and predecessors, which 371 | you can get with the `succ` and `pred` functions. Types in this class: `()`, 372 | `Bool`, `Char`, `Ordering`, `Int`, `Integer`, `Float` and `Double`. 373 | 374 | ~~~~ {.haskell: .ghci name="code"} 375 | ghci> ['a'..'e'] 376 | "abcde" 377 | ghci> [LT .. GT] 378 | [LT,EQ,GT] 379 | ghci> [3 .. 5] 380 | [3,4,5] 381 | ghci> succ 'B' 382 | 'C' 383 | ~~~~ 384 | 385 | `Bounded` members have an upper and a lower bound. 386 | 387 | ~~~~ {.haskell: .ghci name="code"} 388 | ghci> minBound :: Int 389 | -2147483648 390 | ghci> maxBound :: Char 391 | '\1114111' 392 | ghci> maxBound :: Bool 393 | True 394 | ghci> minBound :: Bool 395 | False 396 | ~~~~ 397 | 398 | `minBound` and `maxBound` are interesting because they have a type of 399 | `(Bounded a) => a`. In a sense they are polymorphic constants. 400 | 401 | All tuples are also part of `Bounded` if the components are also in it. 402 | 403 | ~~~~ {.haskell: .ghci name="code"} 404 | ghci> maxBound :: (Bool, Int, Char) 405 | (True,2147483647,'\1114111') 406 | ~~~~ 407 | 408 | `Num` is a numeric typeclass. Its members have the property of being able 409 | to act like numbers. Let's examine the type of a number. 410 | 411 | ~~~~ {.haskell: .ghci name="code"} 412 | ghci> :t 20 413 | 20 :: (Num t) => t 414 | ~~~~ 415 | 416 | It appears that whole numbers are also polymorphic constants. They can 417 | act like any type that's a member of the `Num` typeclass. 418 | 419 | ~~~~ {.haskell: .ghci name="code"} 420 | ghci> 20 :: Int 421 | 20 422 | ghci> 20 :: Integer 423 | 20 424 | ghci> 20 :: Float 425 | 20.0 426 | ghci> 20 :: Double 427 | 20.0 428 | ~~~~ 429 | 430 | Those are types that are in the `Num` typeclass. If we examine the type of 431 | `*`, we'll see that it accepts all numbers. 432 | 433 | ~~~~ {.haskell: .ghci name="code"} 434 | ghci> :t (*) 435 | (*) :: (Num a) => a -> a -> a 436 | ~~~~ 437 | 438 | It takes two numbers of the same type and returns a number of that type. 439 | That's why `(5 :: Int) * (6 :: Integer)` will result in a type error 440 | whereas `5 * (6 :: Integer)` will work just fine and produce an `Integer` 441 | because `5` can act like an `Integer` or an `Int`. 442 | 443 | To join `Num`, a type must already be friends with `Show` and `Eq`. 444 | 445 | `Integral` is also a numeric typeclass. `Num` includes all numbers, 446 | including real numbers and integral numbers, `Integral` includes only 447 | integral (whole) numbers. In this typeclass are `Int` and `Integer`. 448 | 449 | `Floating` includes only floating point numbers, so `Float` and `Double`. 450 | 451 | A very useful function for dealing with numbers is `fromIntegral`. It has 452 | a type declaration of `fromIntegral :: (Integral a, Num b) => a -> b`. 453 | From its type signature we see that it takes an integral number and 454 | turns it into a more general number. That's useful when you want 455 | integral and floating point types to work together nicely. For instance, 456 | the `length` function has a type declaration of `length :: [a] -> Int` 457 | instead of having a more general type of 458 | `(Num b) => length :: [a] -> b`. 459 | I think that's there for historical reasons or something, although in 460 | my opinion, it's pretty stupid. Anyway, if we try to get a length of a 461 | list and then add it to `3.2`, we'll get an error because we tried to add 462 | together an `Int` and a floating point number. So to get around this, we 463 | do `fromIntegral (length [1,2,3,4]) + 3.2` and it all works out. 464 | 465 | Notice that `fromIntegral` has several class constraints in its type 466 | signature. That's completely valid and as you can see, the class 467 | constraints are separated by commas inside the parentheses. 468 | -------------------------------------------------------------------------------- /en/04-syntax-in-functions.md: -------------------------------------------------------------------------------- 1 | Syntax in Functions 2 | =================== 3 | 4 | Pattern matching 5 | ---------------- 6 | 7 | ![four!](img/pattern.png) 8 | 9 | This chapter will cover some of Haskell's cool syntactic constructs and 10 | we'll start with pattern matching. Pattern matching consists of 11 | specifying patterns to which some data should conform and then checking 12 | to see if it does and deconstructing the data according to those 13 | patterns. 14 | 15 | When defining functions, you can define separate function bodies for 16 | different patterns. This leads to really neat code that's simple and 17 | readable. You can pattern match on any data type — numbers, characters, 18 | lists, tuples, etc. Let's make a really trivial function that checks if 19 | the number we supplied to it is a seven or not. 20 | 21 | ~~~~ {.haskell: .hs name="code"} 22 | lucky :: (Integral a) => a -> String 23 | lucky 7 = "LUCKY NUMBER SEVEN!" 24 | lucky x = "Sorry, you're out of luck, pal!" 25 | ~~~~ 26 | 27 | When you call `lucky`, the patterns will be checked from top to bottom and 28 | when it conforms to a pattern, the corresponding function body will be 29 | used. The only way a number can conform to the first pattern here is if 30 | it is 7. If it's not, it falls through to the second pattern, which 31 | matches anything and binds it to `x`. This function could have also been 32 | implemented by using an if statement. But what if we wanted a function 33 | that says the numbers from 1 to 5 and says `"Not between 1 and 5"` for any 34 | other number? Without pattern matching, we'd have to make a pretty 35 | convoluted if then else tree. However, with it: 36 | 37 | ~~~~ {.haskell: .hs name="code"} 38 | sayMe :: (Integral a) => a -> String 39 | sayMe 1 = "One!" 40 | sayMe 2 = "Two!" 41 | sayMe 3 = "Three!" 42 | sayMe 4 = "Four!" 43 | sayMe 5 = "Five!" 44 | sayMe x = "Not between 1 and 5" 45 | ~~~~ 46 | 47 | Note that if we moved the last pattern (the catch-all one) to the top, 48 | it would always say `"Not between 1 and 5"`, because it would catch all 49 | the numbers and they wouldn't have a chance to fall through and be 50 | checked for any other patterns. 51 | 52 | Remember the factorial function we implemented previously? We defined 53 | the factorial of a number `n` as `product [1..n]`. We can also define a 54 | factorial function *recursively*, the way it is usually defined in 55 | mathematics. We start by saying that the factorial of 0 is 1. Then we 56 | state that the factorial of any positive integer is that integer 57 | multiplied by the factorial of its predecessor. Here's how that looks 58 | like translated in Haskell terms. 59 | 60 | ~~~~ {.haskell: .hs name="code"} 61 | factorial :: (Integral a) => a -> a 62 | factorial 0 = 1 63 | factorial n = n * factorial (n - 1) 64 | ~~~~ 65 | 66 | This is the first time we've defined a function recursively. Recursion 67 | is important in Haskell and we'll take a closer look at it later. But in 68 | a nutshell, this is what happens if we try to get the factorial of, say, 69 | 3. It tries to compute `3 * factorial 2`. The factorial of 2 is 70 | `2 * factorial 1`, so for now we have `3 * (2 * factorial 1)`. 71 | `factorial 1` is `1 * factorial 0`, so we have 72 | `3 * (2 * (1 * factorial 0))`. Now here comes the trick — we've defined 73 | the factorial of 0 to be just 1 and 74 | because it encounters that pattern before the catch-all one, it just 75 | returns 1. So the final result is equivalent to `3 * (2 * (1 * 1))`. 76 | Had we written the second pattern on top of the first one, it would 77 | catch all numbers, including 0 and our calculation would never 78 | terminate. That's why order is important when specifying patterns and 79 | it's always best to specify the most specific ones first and then the 80 | more general ones later. 81 | 82 | Pattern matching can also fail. If we define a function like this: 83 | 84 | ~~~~ {.haskell: .hs name="code"} 85 | charName :: Char -> String 86 | charName 'a' = "Albert" 87 | charName 'b' = "Broseph" 88 | charName 'c' = "Cecil" 89 | ~~~~ 90 | 91 | and then try to call it with an input that we didn't expect, this is 92 | what happens: 93 | 94 | ~~~~ {.haskell: .ghci name="code"} 95 | ghci> charName 'a' 96 | "Albert" 97 | ghci> charName 'b' 98 | "Broseph" 99 | ghci> charName 'h' 100 | "*** Exception: tut.hs:(53,0)-(55,21): Non-exhaustive patterns in function charName 101 | ~~~~ 102 | 103 | It complains that we have non-exhaustive patterns, and rightfully so. 104 | When making patterns, we should always include a catch-all pattern so 105 | that our program doesn't crash if we get some unexpected input. 106 | 107 | Pattern matching can also be used on tuples. What if we wanted to make a 108 | function that takes two vectors in a 2D space (that are in the form of 109 | pairs) and adds them together? To add together two vectors, we add their 110 | x components separately and then their y components separately. Here's 111 | how we would have done it if we didn't know about pattern matching: 112 | 113 | ~~~~ {.haskell: .hs name="code"} 114 | addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a) 115 | addVectors a b = (fst a + fst b, snd a + snd b) 116 | ~~~~ 117 | 118 | Well, that works, but there's a better way to do it. Let's modify the 119 | function so that it uses pattern matching. 120 | 121 | ~~~~ {.haskell: .hs name="code"} 122 | addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a) 123 | addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2) 124 | ~~~~ 125 | 126 | There we go! Much better. Note that this is already a catch-all pattern. 127 | The type of `addVectors` (in both cases) is 128 | `addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a)`, 129 | so we are guaranteed to get two pairs as 130 | parameters. 131 | 132 | `fst` and `snd` extract the components of pairs. But what about triples? 133 | Well, there are no provided functions that do that but we can make our 134 | own. 135 | 136 | ~~~~ {.haskell: .hs name="code"} 137 | first :: (a, b, c) -> a 138 | first (x, _, _) = x 139 | 140 | second :: (a, b, c) -> b 141 | second (_, y, _) = y 142 | 143 | third :: (a, b, c) -> c 144 | third (_, _, z) = z 145 | ~~~~ 146 | 147 | The `_` means the same thing as it does in list comprehensions. It means 148 | that we really don't care what that part is, so we just write a `_`. 149 | 150 | Which reminds me, you can also pattern match in list comprehensions. 151 | Check this out: 152 | 153 | ~~~~ {.haskell: .ghci name="code"} 154 | ghci> let xs = [(1,3), (4,3), (2,4), (5,3), (5,6), (3,1)] 155 | ghci> [a+b | (a,b) <- xs] 156 | [4,7,6,8,11,4] 157 | ~~~~ 158 | 159 | Should a pattern match fail, it will just move on to the next element. 160 | 161 | Lists themselves can also be used in pattern matching. You can match 162 | with the empty list `[]` or any pattern that involves `:` and the empty 163 | list. But since `[1,2,3]` is just syntactic sugar for `1:2:3:[]`, you can 164 | also use the former pattern. A pattern like `x:xs` will bind the head of 165 | the list to `x` and the rest of it to `xs`, even if there's only one element 166 | so `xs` ends up being an empty list. 167 | 168 | > *Note*: The `x:xs` pattern is used a lot, especially with recursive 169 | > functions. But patterns that have `:` in them only match against lists of 170 | > length 1 or more. 171 | 172 | If you want to bind, say, the first three elements to variables and the 173 | rest of the list to another variable, you can use something like 174 | `x:y:z:zs`. It will only match against lists that have three elements or 175 | more. 176 | 177 | Now that we know how to pattern match against list, let's make our own 178 | implementation of the `head` function. 179 | 180 | ~~~~ {.haskell: .hs name="code"} 181 | head' :: [a] -> a 182 | head' [] = error "Can't call head on an empty list, dummy!" 183 | head' (x:_) = x 184 | ~~~~ 185 | 186 | Checking if it works: 187 | 188 | ~~~~ {.haskell: .ghci name="code"} 189 | ghci> head' [4,5,6] 190 | 4 191 | ghci> head' "Hello" 192 | 'H' 193 | ~~~~ 194 | 195 | Nice! Notice that if you want to bind to several variables (even if one 196 | of them is just `_` and doesn't actually bind at all), we have to 197 | surround them in parentheses. Also notice the `error` function that we 198 | used. It takes a string and generates a runtime error, using that string 199 | as information about what kind of error occurred. It causes the program 200 | to crash, so it's not good to use it too much. But calling `head` on an 201 | empty list doesn't make sense. 202 | 203 | Let's make a trivial function that tells us some of the first elements 204 | of the list in (in)convenient English form. 205 | 206 | ~~~~ {.haskell: .hs name="code"} 207 | tell :: (Show a) => [a] -> String 208 | tell [] = "The list is empty" 209 | tell (x:[]) = "The list has one element: " ++ show x 210 | tell (x:y:[]) = "The list has two elements: " ++ show x ++ " and " ++ show y 211 | tell (x:y:_) = "This list is long. The first two elements are: " ++ show x ++ " and " ++ show y 212 | ~~~~ 213 | 214 | This function is safe because it takes care of the empty list, a 215 | singleton list, a list with two elements and a list with more than two 216 | elements. Note that `(x:[])` and `(x:y:[])` could be rewritten as `[x]` and 217 | `[x,y]` (because its syntactic sugar, we don't need the parentheses). We 218 | can't rewrite `(x:y:_)` with square brackets because it matches any list 219 | of length 2 or more. 220 | 221 | We already implemented our own `length` function using list comprehension. 222 | Now we'll do it by using pattern matching and a little recursion: 223 | 224 | ~~~~ {.haskell: .hs name="code"} 225 | length' :: (Num b) => [a] -> b 226 | length' [] = 0 227 | length' (_:xs) = 1 + length' xs 228 | ~~~~ 229 | 230 | This is similar to the factorial function we wrote earlier. First we 231 | defined the result of a known input — the empty list. This is also known 232 | as the edge condition. Then in the second pattern we take the list apart 233 | by splitting it into a head and a tail. We say that the length is equal 234 | to 1 plus the length of the tail. We use `_` to match the head because we 235 | don't actually care what it is. Also note that we've taken care of all 236 | possible patterns of a list. The first pattern matches an empty list and 237 | the second one matches anything that isn't an empty list. 238 | 239 | Let's see what happens if we call `length'` on `"ham"`. First, it will check 240 | if it's an empty list. Because it isn't, it falls through to the second 241 | pattern. It matches on the second pattern and there it says that the 242 | length is `1 + length' "am"`, because we broke it into a head and a tail 243 | and discarded the head. O-kay. The `length'` of `"am"` is, similarly, 244 | `1 + length' "m"`. 245 | So right now we have `1 + (1 + length' "m")`. `length' "m"` is 246 | `1 + length' ""` (could also be written as `1 + length' []`). And we've 247 | defined `length' []` to be `0`. So in the end we have `1 + (1 + (1 + 0))`. 248 | 249 | Let's implement `sum`. We know that the sum of an empty list is 0. We 250 | write that down as a pattern. And we also know that the sum of a list is 251 | the head plus the sum of the rest of the list. So if we write that down, 252 | we get: 253 | 254 | ~~~~ {.haskell:nogutter:nocontrols:hs name="code"} 255 | sum' :: (Num a) => [a] -> a 256 | sum' [] = 0 257 | sum' (x:xs) = x + sum' xs 258 | ~~~~ 259 | 260 | There's also a thing called *as patterns*. Those are a handy way of 261 | breaking something up according to a pattern and binding it to names 262 | whilst still keeping a reference to the whole thing. You do that by 263 | putting a name and an `@` in front of a pattern. For instance, the pattern 264 | `xs@(x:y:ys)`. This pattern will match exactly the same thing as `x:y:ys` 265 | but you can easily get the whole list via `xs` instead of repeating 266 | yourself by typing out `x:y:ys` in the function body again. Here's a quick 267 | and dirty example: 268 | 269 | ~~~~ {.haskell:nogutter:nocontrols:hs name="code"} 270 | capital :: String -> String 271 | capital "" = "Empty string, whoops!" 272 | capital all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x] 273 | ~~~~ 274 | 275 | ~~~~ {.haskell:ghci name="code"} 276 | ghci> capital "Dracula" 277 | "The first letter of Dracula is D" 278 | ~~~~ 279 | 280 | Normally we use as patterns to avoid repeating ourselves when matching 281 | against a bigger pattern when we have to use the whole thing again in 282 | the function body. 283 | 284 | One more thing — you can't use `++` in pattern matches. If you tried to 285 | pattern match against `(xs ++ ys)`, what would be in the first and what 286 | would be in the second list? It doesn't make much sense. It would make 287 | sense to match stuff against `(xs ++ [x,y,z])` or just `(xs ++ [x])`, but 288 | because of the nature of lists, you can't do that. 289 | 290 | 291 | 292 | Guards, guards! 293 | --------------- 294 | 295 | ![guards](img/guards.png) 296 | 297 | Whereas patterns are a way of making sure a value conforms to some form 298 | and deconstructing it, guards are a way of testing whether some property 299 | of a value (or several of them) are true or false. That sounds a lot 300 | like an if statement and it's very similar. The thing is that guards are 301 | a lot more readable when you have several conditions and they play 302 | really nicely with patterns. 303 | 304 | Instead of explaining their syntax, let's just dive in and make a 305 | function using guards. We're going to make a simple function that 306 | berates you differently depending on your 307 | [BMI](http://en.wikipedia.org/wiki/Body_mass_index) (body mass index). 308 | Your BMI equals your weight divided by your height squared. If your BMI 309 | is less than 18.5, you're considered underweight. If it's anywhere from 310 | 18.5 to 25 then you're considered normal. 25 to 30 is overweight and 311 | more than 30 is obese. So here's the function (we won't be calculating 312 | it right now, this function just gets a BMI and tells you off) 313 | 314 | ~~~~ {.haskell:hs name="code"} 315 | bmiTell :: (RealFloat a) => a -> String 316 | bmiTell bmi 317 | | bmi <= 18.5 = "You're underweight, you emo, you!" 318 | | bmi <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!" 319 | | bmi <= 30.0 = "You're fat! Lose some weight, fatty!" 320 | | otherwise = "You're a whale, congratulations!" 321 | ~~~~ 322 | 323 | Guards are indicated by pipes that follow a function's name and its 324 | parameters. Usually, they're indented a bit to the right and lined up. A 325 | guard is basically a boolean expression. If it evaluates to `True`, then 326 | the corresponding function body is used. If it evaluates to `False`, 327 | checking drops through to the next guard and so on. If we call this 328 | function with `24.3`, it will first check if that's smaller than or equal 329 | to `18.5`. Because it isn't, it falls through to the next guard. The check 330 | is carried out with the second guard and because 24.3 is less than 25.0, 331 | the second string is returned. 332 | 333 | This is very reminiscent of a big if else tree in imperative languages, 334 | only this is far better and more readable. While big if else trees are 335 | usually frowned upon, sometimes a problem is defined in such a discrete 336 | way that you can't get around them. Guards are a very nice alternative 337 | for this. 338 | 339 | Many times, the last guard is `otherwise`. `otherwise` is defined simply as 340 | `otherwise = True` and catches everything. This is very similar to 341 | patterns, only they check if the input satisfies a pattern but guards 342 | check for boolean conditions. If all the guards of a function evaluate 343 | to `False` (and we haven't provided an `otherwise` catch-all guard), 344 | evaluation falls through to the next *pattern*. That's how patterns and 345 | guards play nicely together. If no suitable guards or patterns are 346 | found, an error is thrown. 347 | 348 | Of course we can use guards with functions that take as many parameters 349 | as we want. Instead of having the user calculate his own BMI before 350 | calling the function, let's modify this function so that it takes a 351 | height and weight and calculates it for us. 352 | 353 | ~~~~ {.haskell:hs name="code"} 354 | bmiTell :: (RealFloat a) => a -> a -> String 355 | bmiTell weight height 356 | | weight / height ^ 2 <= 18.5 = "You're underweight, you emo, you!" 357 | | weight / height ^ 2 <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!" 358 | | weight / height ^ 2 <= 30.0 = "You're fat! Lose some weight, fatty!" 359 | | otherwise = "You're a whale, congratulations!" 360 | ~~~~ 361 | 362 | Let's see if I'm fat ... 363 | 364 | ~~~~ {.haskell:ghci name="code"} 365 | ghci> bmiTell 85 1.90 366 | "You're supposedly normal. Pffft, I bet you're ugly!" 367 | ~~~~ 368 | 369 | Yay! I'm not fat! But Haskell just called me ugly. Whatever! 370 | 371 | Note that there's no `=` right after the function name and its parameters, 372 | before the first guard. Many newbies get syntax errors because they 373 | sometimes put it there. 374 | 375 | Another very simple example: let's implement our own `max` function. If 376 | you remember, it takes two things that can be compared and returns the 377 | larger of them. 378 | 379 | ~~~~ {.haskell:hs name="code"} 380 | max' :: (Ord a) => a -> a -> a 381 | max' a b 382 | | a > b = a 383 | | otherwise = b 384 | ~~~~ 385 | 386 | Guards can also be written inline, although I'd advise against that 387 | because it's less readable, even for very short functions. But to 388 | demonstrate, we could write `max'` like this: 389 | 390 | ~~~~ {.haskell:hs name="code"} 391 | max' :: (Ord a) => a -> a -> a 392 | max' a b | a > b = a | otherwise = b 393 | ~~~~ 394 | 395 | Ugh! Not very readable at all! Moving on: let's implement our own 396 | `compare` by using guards. 397 | 398 | ~~~~ {.haskell:hs name="code"} 399 | myCompare :: (Ord a) => a -> a -> Ordering 400 | a `myCompare` b 401 | | a > b = GT 402 | | a == b = EQ 403 | | otherwise = LT 404 | ~~~~ 405 | 406 | ~~~~ {.haskell:hs name="code"} 407 | ghci> 3 `myCompare` 2 408 | GT 409 | ~~~~ 410 | 411 | > *Note:* Not only can we call functions as infix with backticks, we can 412 | > also define them using backticks. Sometimes it's easier to read that 413 | > way. 414 | 415 | Where!? 416 | ------- 417 | 418 | In the previous section, we defined a BMI calculator function and 419 | berator like this: 420 | 421 | ~~~~ {.haskell:hs name="code"} 422 | bmiTell :: (RealFloat a) => a -> a -> String 423 | bmiTell weight height 424 | | weight / height ^ 2 <= 18.5 = "You're underweight, you emo, you!" 425 | | weight / height ^ 2 <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!" 426 | | weight / height ^ 2 <= 30.0 = "You're fat! Lose some weight, fatty!" 427 | | otherwise = "You're a whale, congratulations!" 428 | ~~~~ 429 | 430 | Notice that we repeat ourselves here three times. We repeat ourselves 431 | three times. Repeating yourself (three times) while programming is about 432 | as desirable as getting kicked inna head. Since we repeat the same 433 | expression three times, it would be ideal if we could calculate it once, 434 | bind it to a name and then use that name instead of the expression. 435 | Well, we can modify our function like this: 436 | 437 | ~~~~ {.haskell:hs name="code"} 438 | bmiTell :: (RealFloat a) => a -> a -> String 439 | bmiTell weight height 440 | | bmi <= 18.5 = "You're underweight, you emo, you!" 441 | | bmi <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!" 442 | | bmi <= 30.0 = "You're fat! Lose some weight, fatty!" 443 | | otherwise = "You're a whale, congratulations!" 444 | where bmi = weight / height ^ 2 445 | ~~~~ 446 | 447 | We put the keyword `where` after the guards (usually it's best to indent 448 | it as much as the pipes are indented) and then we define several names 449 | or functions. These names are visible across the guards and give us the 450 | advantage of not having to repeat ourselves. If we decide that we want 451 | to calculate BMI a bit differently, we only have to change it once. It 452 | also improves readability by giving names to things and can make our 453 | programs faster since stuff like our `bmi` variable here is calculated 454 | only once. We could go a bit overboard and present our function like 455 | this: 456 | 457 | ~~~~ {.haskell:hs name="code"} 458 | bmiTell :: (RealFloat a) => a -> a -> String 459 | bmiTell weight height 460 | | bmi <= skinny = "You're underweight, you emo, you!" 461 | | bmi <= normal = "You're supposedly normal. Pffft, I bet you're ugly!" 462 | | bmi <= fat = "You're fat! Lose some weight, fatty!" 463 | | otherwise = "You're a whale, congratulations!" 464 | where bmi = weight / height ^ 2 465 | skinny = 18.5 466 | normal = 25.0 467 | fat = 30.0 468 | ~~~~ 469 | 470 | The names we define in the where section of a function are only visible 471 | to that function, so we don't have to worry about them polluting the 472 | namespace of other functions. Notice that all the names are aligned at a 473 | single column. If we don't align them nice and proper, Haskell gets 474 | confused because then it doesn't know they're all part of the same 475 | block. 476 | 477 | *where* bindings aren't shared across function bodies of different 478 | patterns. If you want several patterns of one function to access some 479 | shared name, you have to define it globally. 480 | 481 | You can also use where bindings to *pattern match*! We could have 482 | rewritten the where section of our previous function as: 483 | 484 | ~~~~ {.haskell:hs name="code"} 485 | ... 486 | where bmi = weight / height ^ 2 487 | (skinny, normal, fat) = (18.5, 25.0, 30.0) 488 | ~~~~ 489 | 490 | Let's make another fairly trivial function where we get a first and a 491 | last name and give someone back their initials. 492 | 493 | ~~~~ {.haskell:hs name="code"} 494 | initials :: String -> String -> String 495 | initials firstname lastname = [f] ++ ". " ++ [l] ++ "." 496 | where (f:_) = firstname 497 | (l:_) = lastname 498 | ~~~~ 499 | 500 | We could have done this pattern matching directly in the function's 501 | parameters (it would have been shorter and clearer actually) but this 502 | just goes to show that it's possible to do it in where bindings as well. 503 | 504 | Just like we've defined constants in where blocks, you can also define 505 | functions. Staying true to our healthy programming theme, let's make a 506 | function that takes a list of weight-height pairs and returns a list of 507 | BMIs. 508 | 509 | ~~~~ {.haskell:hs name="code"} 510 | calcBmis :: (RealFloat a) => [(a, a)] -> [a] 511 | calcBmis xs = [bmi w h | (w, h) <- xs] 512 | where bmi weight height = weight / height ^ 2 513 | ~~~~ 514 | 515 | And that's all there is to it! The reason we had to introduce `bmi` as a 516 | function in this example is because we can't just calculate one BMI from 517 | the function's parameters. We have to examine the list passed to the 518 | function and there's a different BMI for every pair in there. 519 | 520 | *where* bindings can also be nested. It's a common idiom to make a 521 | function and define some helper function in its *where* clause and then 522 | to give those functions helper functions as well, each with its own 523 | *where* clause. 524 | 525 | 526 | 527 | Let it be 528 | --------- 529 | 530 | Very similar to where bindings are let bindings. Where bindings are a 531 | syntactic construct that let you bind to variables at the end of a 532 | function and the whole function can see them, including all the guards. 533 | Let bindings let you bind to variables anywhere and are expressions 534 | themselves, but are very local, so they don't span across guards. Just 535 | like any construct in Haskell that is used to bind values to names, let 536 | bindings can be used for pattern matching. Let's see them in action! 537 | This is how we could define a function that gives us a cylinder's 538 | surface area based on its height and radius: 539 | 540 | ~~~~ {.haskell:hs name="code"} 541 | cylinder :: (RealFloat a) => a -> a -> a 542 | cylinder r h = 543 | let sideArea = 2 * pi * r * h 544 | topArea = pi * r ^2 545 | in sideArea + 2 * topArea 546 | ~~~~ 547 | 548 | ![let it be](img/letitbe.png) 549 | 550 | The form is `let in `. The names that you 551 | define in the *let* part are accessible to the expression after the *in* 552 | part. As you can see, we could have also defined this with a *where* 553 | binding. Notice that the names are also aligned in a single column. So 554 | what's the difference between the two? For now it just seems that *let* 555 | puts the bindings first and the expression that uses them later whereas 556 | *where* is the other way around. 557 | 558 | The difference is that *let* bindings are expressions themselves. 559 | *where* bindings are just syntactic constructs. Remember when we did the 560 | if statement and it was explained that an if else statement is an 561 | expression and you can cram it in almost anywhere? 562 | 563 | ~~~~ {.haskell:ghci name="code"} 564 | ghci> [if 5 > 3 then "Woo" else "Boo", if 'a' > 'b' then "Foo" else "Bar"] 565 | ["Woo", "Bar"] 566 | ghci> 4 * (if 10 > 5 then 10 else 0) + 2 567 | 42 568 | ~~~~ 569 | 570 | You can also do that with let bindings. 571 | 572 | ~~~~ {.haskell:ghci name="code"} 573 | ghci> 4 * (let a = 9 in a + 1) + 2 574 | 42 575 | ~~~~ 576 | 577 | They can also be used to introduce functions in a local scope: 578 | 579 | ~~~~ {.haskell:ghci name="code"} 580 | ghci> [let square x = x * x in (square 5, square 3, square 2)] 581 | [(25,9,4)] 582 | ~~~~ 583 | 584 | If we want to bind to several variables inline, we obviously can't align 585 | them at columns. That's why we can separate them with semicolons. 586 | 587 | ~~~~ {.haskell:ghci name="code"} 588 | ghci> (let a = 100; b = 200; c = 300 in a*b*c, let foo="Hey "; bar = "there!" in foo ++ bar) 589 | (6000000,"Hey there!") 590 | ~~~~ 591 | 592 | You don't have to put a semicolon after the last binding but you can if 593 | you want. Like we said before, you can pattern match with *let* 594 | bindings. They're very useful for quickly dismantling a tuple into 595 | components and binding them to names and such. 596 | 597 | ~~~~ {.haskell:ghci name="code"} 598 | ghci> (let (a,b,c) = (1,2,3) in a+b+c) * 100 599 | 600 600 | ~~~~ 601 | 602 | You can also put *let* bindings inside list comprehensions. Let's 603 | rewrite our previous example of calculating lists of weight-height pairs 604 | to use a *let* inside a list comprehension instead of defining an 605 | auxiliary function with a *where*. 606 | 607 | ~~~~ {.haskell:hs name="code"} 608 | calcBmis :: (RealFloat a) => [(a, a)] -> [a] 609 | calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2] 610 | ~~~~ 611 | 612 | We include a *let* inside a list comprehension much like we would a 613 | predicate, only it doesn't filter the list, it only binds to names. The 614 | names defined in a *let* inside a list comprehension are visible to the 615 | output function (the part before the |) and all predicates and sections 616 | that come after of the binding. So we could make our function return 617 | only the BMIs of fat people: 618 | 619 | ~~~~ {.haskell:hs name="code"} 620 | calcBmis :: (RealFloat a) => [(a, a)] -> [a] 621 | calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2, bmi >= 25.0] 622 | ~~~~ 623 | 624 | We can't use the `bmi` name in the `(w, h) <- xs` part because it's defined 625 | prior to the *let* binding. 626 | 627 | We omitted the *in* part of the *let* binding when we used them in list 628 | comprehensions because the visibility of the names is already predefined 629 | there. However, we could use a *let in* binding in a predicate and the 630 | names defined would only be visible to that predicate. The *in* part can 631 | also be omitted when defining functions and constants directly in GHCi. 632 | If we do that, then the names will be visible throughout the entire 633 | interactive session. 634 | 635 | ~~~~ {.haskell:ghci name="code"} 636 | ghci> let zoot x y z = x * y + z 637 | ghci> zoot 3 9 2 638 | 29 639 | ghci> let boot x y z = x * y + z in boot 3 4 2 640 | 14 641 | ghci> boot 642 | :1:0: Not in scope: `boot' 643 | ~~~~ 644 | 645 | If *let* bindings are so cool, why not use them all the time instead of 646 | *where* bindings, you ask? Well, since *let* bindings are expressions 647 | and are fairly local in their scope, they can't be used across guards. 648 | Some people prefer *where* bindings because the names come after the 649 | function they're being used in. That way, the function body is closer to 650 | its name and type declaration and to some that's more readable. 651 | 652 | Case expressions 653 | ---------------- 654 | 655 | ![case](img/case.png) 656 | 657 | Many imperative languages (C, C++, Java, etc.) have case syntax and if 658 | you've ever programmed in them, you probably know what it's about. It's 659 | about taking a variable and then executing blocks of code for specific 660 | values of that variable and then maybe including a catch-all block of 661 | code in case the variable has some value for which we didn't set up a 662 | case. 663 | 664 | Haskell takes that concept and one-ups it. Like the name implies, case 665 | expressions are, well, expressions, much like if else expressions and 666 | *let* bindings. Not only can we evaluate expressions based on the 667 | possible cases of the value of a variable, we can also do pattern 668 | matching. Hmmm, taking a variable, pattern matching it, evaluating 669 | pieces of code based on its value, where have we heard this before? Oh 670 | yeah, pattern matching on parameters in function definitions! Well, 671 | that's actually just syntactic sugar for case expressions. These two 672 | pieces of code do the same thing and are interchangeable: 673 | 674 | ~~~~ {.haskell:hs name="code"} 675 | head' :: [a] -> a 676 | head' [] = error "No head for empty lists!" 677 | head' (x:_) = x 678 | ~~~~ 679 | 680 | ~~~~ {.haskell:hs name="code"} 681 | head' :: [a] -> a 682 | head' xs = case xs of [] -> error "No head for empty lists!" 683 | (x:_) -> x 684 | ~~~~ 685 | 686 | As you can see, the syntax for case expressions is pretty simple: 687 | 688 | ~~~~ {.haskell:hs name="code"} 689 | case expression of pattern -> result 690 | pattern -> result 691 | pattern -> result 692 | ... 693 | ~~~~ 694 | 695 | `expression` is matched against the patterns. The pattern matching action 696 | is the same as expected: the first pattern that matches the expression 697 | is used. If it falls through the whole case expression and no suitable 698 | pattern is found, a runtime error occurs. 699 | 700 | Whereas pattern matching on function parameters can only be done when 701 | defining functions, case expressions can be used pretty much anywhere. 702 | For instance: 703 | 704 | ~~~~ {.haskell:hs name="code"} 705 | describeList :: [a] -> String 706 | describeList xs = "The list is " ++ case xs of [] -> "empty." 707 | [x] -> "a singleton list." 708 | xs -> "a longer list." 709 | ~~~~ 710 | 711 | They are useful for pattern matching against something in the middle of 712 | an expression. Because pattern matching in function definitions is 713 | syntactic sugar for case expressions, we could have also defined this 714 | like so: 715 | 716 | ~~~~ {.haskell:hs name="code"} 717 | describeList :: [a] -> String 718 | describeList xs = "The list is " ++ what xs 719 | where what [] = "empty." 720 | what [x] = "a singleton list." 721 | what xs = "a longer list." 722 | ~~~~ 723 | -------------------------------------------------------------------------------- /en/05-recursion.md: -------------------------------------------------------------------------------- 1 | Recursion 2 | ========= 3 | 4 | 5 | 6 | Hello recursion! 7 | ---------------- 8 | 9 | ![SOVIET RUSSIA](img/recursion.png) 10 | 11 | We mention recursion briefly in the previous chapter. In this chapter, 12 | we'll take a closer look at recursion, why it's important to Haskell and 13 | how we can work out very concise and elegant solutions to problems by 14 | thinking recursively. 15 | 16 | If you still don't know what recursion is, read this sentence. Haha! 17 | Just kidding! Recursion is actually a way of defining functions in which 18 | the function is applied inside its own definition. Definitions in 19 | mathematics are often given recursively. For instance, the Fibonacci 20 | sequence is defined recursively. First, we define the first two 21 | Fibonacci numbers non-recursively. We say that $F(0) = 0$ and 22 | $F(1) = 1$, meaning that the 0th and 1st Fibonacci numbers are 0 and 1, 23 | respectively. Then we say that for any other natural number, that 24 | Fibonacci number is the sum of the previous two Fibonacci numbers. So 25 | $F(n) = F(n-1) + F(n-2)$. That way, $F(3)$ is $F(2) + F(1)$, which is 26 | $(F(1) + F(0)) + F(1)$. Because we've now come down to only 27 | non-recursively defined Fibonacci numbers, we can safely say that $F(3)$ 28 | is 2. Having an element or two in a recursion definition defined 29 | non-recursively (like $F(0)$ and $F(1)$ here) is also called the *edge 30 | condition* and is important if you want your recursive function to 31 | terminate. If we hadn't defined $F(0)$ and $F(1)$ non recursively, you'd 32 | never get a solution any number because you'd reach 0 and then you'd go 33 | into negative numbers. All of a sudden, you'd be saying that $F(-2000)$ 34 | is $F(-2001) + F(-2002)$ and there still wouldn't be an end in sight! 35 | 36 | Recursion is important to Haskell because unlike imperative languages, 37 | you do computations in Haskell by declaring what something *is* instead 38 | of declaring *how* you get it. That's why there are no while loops or 39 | for loops in Haskell and instead we many times have to use recursion to 40 | declare what something is. 41 | 42 | Maximum awesome 43 | --------------- 44 | 45 | The `maximum` function takes a list of things that can be ordered (e.g. 46 | instances of the `Ord` typeclass) and returns the biggest of them. Think 47 | about how you'd implement that in an imperative fashion. You'd probably 48 | set up a variable to hold the maximum value so far and then you'd loop 49 | through the elements of a list and if an element is bigger than then the 50 | current maximum value, you'd replace it with that element. The maximum 51 | value that remains at the end is the result. Whew! That's quite a lot of 52 | words to describe such a simple algorithm! 53 | 54 | Now let's see how we'd define it recursively. We could first set up an 55 | edge condition and say that the maximum of a singleton list is equal to 56 | the only element in it. Then we can say that the maximum of a longer 57 | list is the head if the head is bigger than the maximum of the tail. If 58 | the maximum of the tail is bigger, well, then it's the maximum of the 59 | tail. That's it! Now let's implement that in Haskell. 60 | 61 | ~~~~ {.haskell:hs name="code"} 62 | maximum' :: (Ord a) => [a] -> a 63 | maximum' [] = error "maximum of empty list" 64 | maximum' [x] = x 65 | maximum' (x:xs) 66 | | x > maxTail = x 67 | | otherwise = maxTail 68 | where maxTail = maximum' xs 69 | ~~~~ 70 | 71 | As you can see, pattern matching goes great with recursion! Most 72 | imperative languages don't have pattern matching so you have to make a 73 | lot of if else statements to test for edge conditions. Here, we simply 74 | put them out as patterns. So the first edge condition says that if the 75 | list is empty, crash! Makes sense because what's the maximum of an empty 76 | list? I don't know. The second pattern also lays out an edge condition. 77 | It says that if it's the singleton list, just give back the only 78 | element. 79 | 80 | Now the third pattern is where the action happens. We use pattern 81 | matching to split a list into a head and a tail. This is a very common 82 | idiom when doing recursion with lists, so get used to it. We use a 83 | *where* binding to define `maxTail` as the maximum of the rest of the 84 | list. Then we check if the head is greater than the maximum of the rest 85 | of the list. If it is, we return the head. Otherwise, we return the 86 | maximum of the rest of the list. 87 | 88 | Let's take an example list of numbers and check out how this would work 89 | on them: `[2,5,1]`. If we call `maximum'` on that, the first two patterns 90 | won't match. The third one will and the list is split into `2` and `[5,1]`. 91 | The *where* clause wants to know the maximum of `[5,1]`, so we follow that 92 | route. It matches the third pattern again and `[5,1]` is split into `5` and 93 | `[1]`. Again, the `where` clause wants to know the maximum of `[1]`. Because 94 | that's the edge condition, it returns `1`. Finally! So going up one step, 95 | comparing `5` to the maximum of `[1]` (which is `1`), we obviously get back `5`. 96 | So now we know that the maximum of `[5,1]` is `5`. We go up one step again 97 | where we had `2` and `[5,1]`. Comparing `2` with the maximum of `[5,1]`, which 98 | is `5`, we choose `5`. 99 | 100 | An even clearer way to write this function is to use `max`. If you 101 | remember, `max` is a function that takes two numbers and returns the 102 | bigger of them. Here's how we could rewrite `maximum'` by using `max`: 103 | 104 | ~~~~ {.haskell:hs name="code"} 105 | maximum' :: (Ord a) => [a] -> a 106 | maximum' [] = error "maximum of empty list" 107 | maximum' [x] = x 108 | maximum' (x:xs) = max x (maximum' xs) 109 | ~~~~ 110 | 111 | How's that for elegant! In essence, the maximum of a list is the max of 112 | the first element and the maximum of the tail. 113 | 114 | ![max](img/maxs.png) 115 | 116 | A few more recursive functions 117 | ------------------------------ 118 | 119 | Now that we know how to generally think recursively, let's implement a 120 | few functions using recursion. First off, we'll implement `replicate`. 121 | `replicate` takes an `Int` and some element and returns a list that has 122 | several repetitions of the same element. For instance, `replicate 3 5` 123 | returns `[5,5,5]`. Let's think about the edge condition. My guess is that 124 | the edge condition is 0 or less. If we try to replicate something zero 125 | times, it should return an empty list. Also for negative numbers, 126 | because it doesn't really make sense. 127 | 128 | ~~~~ {.haskell:hs name="code"} 129 | replicate' :: (Num i, Ord i) => i -> a -> [a] 130 | replicate' n x 131 | | n <= 0 = [] 132 | | otherwise = x:replicate' (n-1) x 133 | ~~~~ 134 | 135 | We used guards here instead of patterns because we're testing for a 136 | boolean condition. If `n` is less than or equal to 0, return an empty 137 | list. Otherwise return a list that has `x` as the first element and then `x` 138 | replicated n-1 times as the tail. Eventually, the `(n-1)` part will cause 139 | our function to reach the edge condition. 140 | 141 | > *Note:* `Num` is not a subclass of `Ord`. That means that what constitutes 142 | > for a number doesn't really have to adhere to an ordering. So that's why 143 | > we have to specify both the `Num` and `Ord` class constraints when doing 144 | > addition or subtraction and also comparison. 145 | 146 | Next up, we'll implement `take`. It takes a certain number of elements 147 | from a list. For instance, `take 3 [5,4,3,2,1]` will return `[5,4,3]`. If we 148 | try to take 0 or less elements from a list, we get an empty list. Also 149 | if we try to take anything from an empty list, we get an empty list. 150 | Notice that those are two edge conditions right there. So let's write 151 | that out: 152 | 153 | ~~~~ {.haskell:hs name="code"} 154 | take' :: (Num i, Ord i) => i -> [a] -> [a] 155 | take' n _ 156 | | n <= 0 = [] 157 | take' _ [] = [] 158 | take' n (x:xs) = x : take' (n-1) xs 159 | ~~~~ 160 | 161 | ![painter](img/painter.png) 162 | 163 | The first pattern specifies that if we try to take a 0 or negative 164 | number of elements, we get an empty list. Notice that we're using `_` to 165 | match the list because we don't really care what it is in this case. 166 | Also notice that we use a guard, but without an `otherwise` part. That 167 | means that if `n` turns out to be more than 0, the matching will fall 168 | through to the next pattern. The second pattern indicates that if we try 169 | to take anything from an empty list, we get an empty list. The third 170 | pattern breaks the list into a head and a tail. And then we state that 171 | taking `n` elements from a list equals a list that has `x` as the head and 172 | then a list that takes `n-1` elements from the tail as a tail. Try using a 173 | piece of paper to write down how the evaluation would look like if we 174 | try to take, say, 3 from `[4,3,2,1]`. 175 | 176 | `reverse` simply reverses a list. Think about the edge condition. What is 177 | it? Come on ... it's the empty list! An empty list reversed equals the 178 | empty list itself. O-kay. What about the rest of it? Well, you could say 179 | that if we split a list to a head and a tail, the reversed list is equal 180 | to the reversed tail and then the head at the end. 181 | 182 | ~~~~ {.haskell:hs name="code"} 183 | reverse' :: [a] -> [a] 184 | reverse' [] = [] 185 | reverse' (x:xs) = reverse' xs ++ [x] 186 | ~~~~ 187 | 188 | There we go! 189 | 190 | Because Haskell supports infinite lists, our recursion doesn't really 191 | have to have an edge condition. But if it doesn't have it, it will 192 | either keep churning at something infinitely or produce an infinite data 193 | structure, like an infinite list. The good thing about infinite lists 194 | though is that we can cut them where we want. `repeat` takes an element 195 | and returns an infinite list that just has that element. A recursive 196 | implementation of that is really easy, watch. 197 | 198 | ~~~~ {.haskell:hs name="code"} 199 | repeat' :: a -> [a] 200 | repeat' x = x:repeat' x 201 | ~~~~ 202 | 203 | Calling `repeat 3` will give us a list that starts with `3` and then has an 204 | infinite amount of 3's as a tail. So calling `repeat 3` would evaluate 205 | like `3:repeat 3`, which is `3:(3:repeat 3)`, which is `3:(3:(3:repeat 3))`, 206 | etc. `repeat 3` will never finish evaluating, whereas `take 5 (repeat 3)` 207 | will give us a list of five 3's. So essentially it's like doing 208 | `replicate 5 3`. 209 | 210 | `zip` takes two lists and zips them together. `zip [1,2,3] [2,3]` returns 211 | `[(1,2),(2,3)]`, because it truncates the longer list to match the length 212 | of the shorter one. How about if we zip something with an empty list? 213 | Well, we get an empty list back then. So there's our edge condition. 214 | However, `zip` takes two lists as parameters, so there are actually two 215 | edge conditions. 216 | 217 | ~~~~ {.haskell:hs name="code"} 218 | zip' :: [a] -> [b] -> [(a,b)] 219 | zip' _ [] = [] 220 | zip' [] _ = [] 221 | zip' (x:xs) (y:ys) = (x,y):zip' xs ys 222 | ~~~~ 223 | 224 | First two patterns say that if the first list or second list is empty, 225 | we get an empty list. The third one says that two lists zipped are equal 226 | to pairing up their heads and then tacking on the zipped tails. Zipping 227 | `[1,2,3]` and `['a','b']` will eventually try to zip `[3]` with `[]`. The edge 228 | condition patterns kick in and so the result is `(1,'a'):(2,'b'):[]`, 229 | which is exactly the same as `[(1,'a'),(2,'b')]`. 230 | 231 | Let's implement one more standard library function — `elem`. It takes an 232 | element and a list and sees if that element is in the list. The edge 233 | condition, as is most of the times with lists, is the empty list. We 234 | know that an empty list contains no elements, so it certainly doesn't 235 | have the droids we're looking for. 236 | 237 | ~~~~ {.haskell:hs name="code"} 238 | elem' :: (Eq a) => a -> [a] -> Bool 239 | elem' a [] = False 240 | elem' a (x:xs) 241 | | a == x = True 242 | | otherwise = a `elem'` xs 243 | ~~~~ 244 | 245 | Pretty simple and expected. If the head isn't the element then we check 246 | the tail. If we reach an empty list, the result is `False`. 247 | 248 | Quick, sort! 249 | ------------ 250 | 251 | We have a list of items that can be sorted. Their type is an instance of 252 | the `Ord` typeclass. And now, we want to sort them! There's a very cool 253 | algorithm for sorting called quicksort. It's a very clever way of sorting 254 | items. While it takes upwards of 10 lines to implement quicksort in 255 | imperative languages, the implementation is much shorter and elegant in 256 | Haskell. Quicksort has become a sort of poster child for Haskell. 257 | Therefore, let's implement it here, even though implementing quicksort 258 | in Haskell is considered really cheesy because everyone does it to 259 | showcase how elegant Haskell is. 260 | 261 | ![quickman](img/quickman.png) 262 | 263 | So, the type signature is going to be 264 | `quicksort :: (Ord a) => [a] -> [a]`. 265 | No surprises there. The edge condition? Empty list, as is expected. 266 | A sorted empty list is an empty list. Now here comes the main algorithm: 267 | *a sorted list is a list that has all the values smaller than (or equal 268 | to) the head of the list in front (and those values are sorted), then 269 | comes the head of the list in the middle and then come all the values 270 | that are bigger than the head (they're also sorted).* Notice that we 271 | said *sorted* two times in this definition, so we'll probably have to 272 | make the recursive call twice! Also notice that we defined it using the 273 | verb *is* to define the algorithm instead of saying *do this, do that, 274 | then do that ...*. That's the beauty of functional programming! How are 275 | we going to filter the list so that we get only the elements smaller 276 | than the head of our list and only elements that are bigger? List 277 | comprehensions. So, let's dive in and define this function. 278 | 279 | ~~~~ {.haskell:hs name="code"} 280 | quicksort :: (Ord a) => [a] -> [a] 281 | quicksort [] = [] 282 | quicksort (x:xs) = 283 | let smallerSorted = quicksort [a | a <- xs, a <= x] 284 | biggerSorted = quicksort [a | a <- xs, a > x] 285 | in smallerSorted ++ [x] ++ biggerSorted 286 | ~~~~ 287 | 288 | Let's give it a small test run to see if it appears to behave correctly. 289 | 290 | ~~~~ {.haskell:ghci name="code"} 291 | ghci> quicksort [10,2,5,3,1,6,7,4,2,3,4,8,9] 292 | [1,2,2,3,3,4,4,5,6,7,8,9,10] 293 | ghci> quicksort "the quick brown fox jumps over the lazy dog" 294 | " abcdeeefghhijklmnoooopqrrsttuuvwxyz" 295 | ~~~~ 296 | 297 | Booyah! That's what I'm talking about! So if we have, say 298 | `[5,1,9,4,6,7,3]` and we want to sort it, this algorithm will first take 299 | the head, which is `5` and then put it in the middle of two lists that are 300 | smaller and bigger than it. So at one point, you'll have 301 | `[1,4,3] ++ [5] ++ [9,6,7]`. We know that once the list is sorted completely, 302 | the number `5` will stay in the fourth place since there are 3 numbers lower 303 | than it and 3 numbers higher than it. Now, if we sort `[1,4,3]` and `[9,6,7]`, we 304 | have a sorted list! We sort the two lists using the same function. 305 | Eventually, we'll break it up so much that we reach empty lists and an 306 | empty list is already sorted in a way, by virtue of being empty. Here's 307 | an illustration: 308 | 309 | ![quicksort](img/quicksort.png) 310 | 311 | An element that is in place and won't move anymore is represented in 312 | orange. If you read them from left to right, you'll see the sorted list. 313 | Although we chose to compare all the elements to the heads, we could 314 | have used any element to compare against. In quicksort, an element that 315 | you compare against is called a pivot. They're in green here. We chose 316 | the head because it's easy to get by pattern matching. The elements that 317 | are smaller than the pivot are light green and elements larger than the 318 | pivot are dark green. The yellowish gradient thing represents an 319 | application of quicksort. 320 | 321 | Thinking recursively 322 | -------------------- 323 | 324 | We did quite a bit of recursion so far and as you've probably noticed, 325 | there's a pattern here. Usually you define an edge case and then you 326 | define a function that does something between some element and the 327 | function applied to the rest. It doesn't matter if it's a list, a tree 328 | or any other data structure. A sum is the first element of a list plus 329 | the sum of the rest of the list. A product of a list is the first 330 | element of the list times the product of the rest of the list. The 331 | length of a list is one plus the length of the tail of the list. 332 | Ekcetera, ekcetera ... 333 | 334 | ![brain](img/brain.png) 335 | 336 | Of course, these also have edge cases. Usually the edge case is some 337 | scenario where a recursive application doesn't make sense. When dealing 338 | with lists, the edge case is most often the empty list. If you're 339 | dealing with trees, the edge case is usually a node that doesn't have 340 | any children. 341 | 342 | It's similar when you're dealing with numbers recursively. Usually it 343 | has to do with some number and the function applied to that number 344 | modified. We did the factorial function earlier and it's the product of 345 | a number and the factorial of that number minus one. Such a recursive 346 | application doesn't make sense with zero, because factorials are defined 347 | only for positive integers. Often the edge case value turns out to be an 348 | identity. The identity for multiplication is 1 because if you multiply 349 | something by 1, you get that something back. Also when doing sums of 350 | lists, we define the sum of an empty list as 0 and 0 is the identity for 351 | addition. In quicksort, the edge case is the empty list and the identity 352 | is also the empty list, because if you add an empty list to a list, you 353 | just get the original list back. 354 | 355 | So when trying to think of a recursive way to solve a problem, try to 356 | think of when a recursive solution doesn't apply and see if you can use 357 | that as an edge case, think about identities and think about whether 358 | you'll break apart the parameters of the function (for instance, lists 359 | are usually broken into a head and a tail via pattern matching) and on 360 | which part you'll use the recursive call. 361 | -------------------------------------------------------------------------------- /en/10-functionally-solving-problems.md: -------------------------------------------------------------------------------- 1 | Functionally Solving Problems 2 | ============================= 3 | 4 | In this chapter, we'll take a look at a few interesting problems and how 5 | to think functionally to solve them as elegantly as possible. We 6 | probably won't be introducing any new concepts, we'll just be flexing 7 | our newly acquired Haskell muscles and practicing our coding skills. 8 | Each section will present a different problem. First we'll describe the 9 | problem, then we'll try and find out what the best (or least worst) way 10 | of solving it is. 11 | 12 | 13 | 14 | Reverse Polish notation calculator 15 | ---------------------------------- 16 | 17 | Usually when we write mathematical expressions in school, we write them 18 | in an infix manner. For instance, we write `10 - (4 + 3) * 2`. `+`, `*` and 19 | `-` are infix operators, just like the infix functions we met in Haskell 20 | (`+`, `` `elem` ``, etc.). This makes it handy because we, as humans, can 21 | parse it easily in our minds by looking at such an expression. The 22 | downside to it is that we have to use parentheses to denote precedence. 23 | 24 | [Reverse Polish 25 | notation](http://en.wikipedia.org/wiki/Reverse_Polish_notation) is 26 | another way of writing down mathematical expressions. Initially it looks 27 | a bit weird, but it's actually pretty easy to understand and use because 28 | there's no need for parentheses and it's very easy to punch into a 29 | calculator. While most modern calculators use infix notation, some 30 | people still swear by RPN calculators. This is what the previous infix 31 | expression looks like in RPN: `10 4 3 + 2 * -`. How do we calculate what 32 | the result of that is? Well, think of a stack. You go over the 33 | expression from left to right. Every time a number is encountered, push 34 | it on to the stack. When we encounter an operator, take the two numbers 35 | that are on top of the stack (we also say that we *pop* them), use the 36 | operator and those two and then push the resulting number back onto the 37 | stack. When you reach the end of the expression, you should be left with 38 | a single number if the expression was well-formed and that number 39 | represents the result. 40 | 41 | ![this expression](img/rpn.png) 42 | 43 | Let's go over the expression `10 4 3 + 2 * -` together! First we push `10` 44 | on to the stack and the stack is now `10`. The next item is `4`, so we push 45 | it to the stack as well. The stack is now `10, 4`. We do the same with `3` 46 | and the stack is now `10, 4, 3`. And now, we encounter an operator, namely 47 | `+`! We pop the two top numbers from the stack (so now the stack is just 48 | `10`), add those numbers together and push that result to the stack. The 49 | stack is now `10, 7`. We push `2` to the stack, the stack for now is 50 | `10, 7, 2`. We've encountered an operator again, so let's pop `7` and `2` off the 51 | stack, multiply them and push that result to the stack. Multiplying `7` 52 | and `2` produces a `14`, so the stack we have now is `10, 14`. Finally, 53 | there's a `-`. We pop `10` and `14` from the stack, subtract `14` from `10` and 54 | push that back. The number on the stack is now `-4` and because there are 55 | no more numbers or operators in our expression, that's our result! 56 | 57 | Now that we know how we'd calculate any RPN expression by hand, let's 58 | think about how we could make a Haskell function that takes as its 59 | parameter a string that contains a RPN expression, like 60 | `"10 4 3 + 2 * -"` and gives us back its result. 61 | 62 | What would the type of that function be? We want it to take a string as 63 | a parameter and produce a number as its result. So it will probably be 64 | something like `solveRPN :: (Num a) => String -> a`. 65 | 66 | > *Protip:* it really helps to first think what the type declaration of a 67 | > function should be before concerning ourselves with the implementation 68 | > and then write it down. In Haskell, a function's type declaration tells 69 | > us a whole lot about the function, due to the very strong type system. 70 | 71 | ![HA HA HA](img/calculator.png) 72 | 73 | Cool. When implementing a solution to a problem in Haskell, it's also 74 | good to think back on how you did it by hand and maybe try to see if you 75 | can gain any insight from that. Here we see that we treated every number 76 | or operator that was separated by a space as a single item. So it might 77 | help us if we start by breaking a string like 78 | `"10 4 3 + 2 * -"` into a 79 | list of items like `["10","4","3","+","2","*","-"]`. 80 | 81 | Next up, what did we do with that list of items in our head? We went 82 | over it from left to right and kept a stack as we did that. Does the 83 | previous sentence remind you of anything? Remember, in the section about 84 | [folds](#folds), we said that pretty much any 85 | function where you traverse a list from left to right or right to left 86 | one element by element and build up (accumulate) some result (whether 87 | it's a number, a list, a stack, whatever) can be implemented with a 88 | fold. 89 | 90 | In this case, we're going to use a left fold, because we go over the 91 | list from left to right. The accumulator value will be our stack and 92 | hence, the result from the fold will also be a stack, only as we've 93 | seen, it will only have one item. 94 | 95 | One more thing to think about is, well, how are we going to represent 96 | the stack? I propose we use a list. Also I propose that we keep the top 97 | of our stack at the head of the list. That's because adding to the head 98 | (beginning) of a list is much faster than adding to the end of it. So if 99 | we have a stack of, say, `10, 4, 3`, we'll represent that as the list 100 | `[3,4,10]`. 101 | 102 | Now we have enough information to roughly sketch our function. It's 103 | going to take a string, like, `"10 4 3 + 2 * -"` and break it down into a 104 | list of items by using `words` to get `["10","4","3","+","2","*","-"]`. 105 | Next, we'll do a left fold over that list and end up with a stack that 106 | has a single item, so `[-4]`. We take that single item out of the list and 107 | that's our final result! 108 | 109 | So here's a sketch of that function: 110 | 111 | ~~~~ {.haskell:hs name="code"} 112 | import Data.List 113 | 114 | solveRPN :: (Num a) => String -> a 115 | solveRPN expression = head (foldl foldingFunction [] (words expression)) 116 | where foldingFunction stack item = ... 117 | ~~~~ 118 | 119 | We take the expression and turn it into a list of items. Then we fold 120 | over that list of items with the folding function. Mind the `[]`, which 121 | represents the starting accumulator. The accumulator is our stack, so `[]` 122 | represents an empty stack, which is what we start with. After getting 123 | the final stack with a single item, we call `head` on that list to get the 124 | item out and then we apply `read`. 125 | 126 | So all that's left now is to implement a folding function that will take 127 | a stack, like `[4,10]`, and an item, like `"3"` and return a new stack 128 | `[3,4,10]`. If the stack is `[4,10]` and the item `"*"`, then it will have to 129 | return `[40]`. But before that, let's turn our function into [point-free 130 | style](#composition) because it has a lot of 131 | parentheses that are kind of freaking me out: 132 | 133 | ~~~~ {.haskell:hs name="code"} 134 | import Data.List 135 | 136 | solveRPN :: (Num a) => String -> a 137 | solveRPN = head . foldl foldingFunction [] . words 138 | where foldingFunction stack item = ... 139 | ~~~~ 140 | 141 | Ah, there we go. Much better. So, the folding function will take a stack 142 | and an item and return a new stack. We'll use pattern matching to get 143 | the top items of a stack and to pattern match against operators like 144 | `"*"` and `"-"`. 145 | 146 | ~~~~ {.haskell:hs name="code"} 147 | solveRPN :: (Num a, Read a) => String -> a 148 | solveRPN = head . foldl foldingFunction [] . words 149 | where foldingFunction (x:y:ys) "*" = (x * y):ys 150 | foldingFunction (x:y:ys) "+" = (x + y):ys 151 | foldingFunction (x:y:ys) "-" = (y - x):ys 152 | foldingFunction xs numberString = read numberString:xs 153 | ~~~~ 154 | 155 | We laid this out as four patterns. The patterns will be tried from top 156 | to bottom. First the folding function will see if the current item is 157 | `"*"`. If it is, then it will take a list like `[3,4,9,3]` and call its 158 | first two elements `x` and `y` respectively. So in this case, `x` would be `3` 159 | and `y` would be `4`. `ys` would be `[9,3]`. It will return a list that's just 160 | like `ys`, only it has `x` and `y` multiplied as its head. So with this we pop 161 | the two topmost numbers off the stack, multiply them and push the result 162 | back on to the stack. If the item is not `"*"`, the pattern matching will 163 | fall through and `"+"` will be checked, and so on. 164 | 165 | If the item is none of the operators, then we assume it's a string that 166 | represents a number. If it's a number, we just call `read` on that string 167 | to get a number from it and return the previous stack but with that 168 | number pushed to the top. 169 | 170 | And that's it! Also noticed that we added an extra class constraint of 171 | `Read a` to the function declaration, because we call `read` on our string 172 | to get the number. So this declaration means that the result can be of 173 | any type that's part of the `Num` and `Read` typeclasses (like `Int`, `Float`, 174 | etc.). 175 | 176 | For the list of items `["2","3","+"]`, our function will start folding 177 | from the left. The initial stack will be `[]`. It will call the folding 178 | function with `[]` as the stack (accumulator) and `"2"` as the item. Because 179 | that item is not an operator, it will be `read` and the added to the 180 | beginning of `[]`. So the new stack is now `[2]` and the folding function 181 | will be called with `[2]` as the stack and `["3"]` as the item, producing a 182 | new stack of `[3,2]`. Then, it's called for the third time with `[3,2]` as 183 | the stack and `"+"` as the item. This causes these two numbers to be 184 | popped off the stack, added together and pushed back. The final stack is 185 | `[5]`, which is the number that we return. 186 | 187 | Let's play around with our function: 188 | 189 | ~~~~ {.haskell:hs name="code"} 190 | ghci> solveRPN "10 4 3 + 2 * -" 191 | -4 192 | ghci> solveRPN "2 3 +" 193 | 5 194 | ghci> solveRPN "90 34 12 33 55 66 + * - +" 195 | -3947 196 | ghci> solveRPN "90 34 12 33 55 66 + * - + -" 197 | 4037 198 | ghci> solveRPN "90 34 12 33 55 66 + * - + -" 199 | 4037 200 | ghci> solveRPN "90 3 -" 201 | 87 202 | ~~~~ 203 | 204 | Cool, it works! One nice thing about this function is that it can be 205 | easily modified to support various other operators. They don't even have 206 | to be binary operators. For instance, we can make an operator `"log"` that 207 | just pops one number off the stack and pushes back its logarithm. We can 208 | also make a ternary operators that pop three numbers off the stack and 209 | push back a result or operators like `"sum"` which pop off all the numbers 210 | and push back their sum. 211 | 212 | Let's modify our function to take a few more operators. For simplicity's 213 | sake, we'll change its type declaration so that it returns a number of 214 | type `Float`. 215 | 216 | ~~~~ {.haskell:hs name="code"} 217 | import Data.List 218 | 219 | solveRPN :: String -> Float 220 | solveRPN = head . foldl foldingFunction [] . words 221 | where foldingFunction (x:y:ys) "*" = (x * y):ys 222 | foldingFunction (x:y:ys) "+" = (x + y):ys 223 | foldingFunction (x:y:ys) "-" = (y - x):ys 224 | foldingFunction (x:y:ys) "/" = (y / x):ys 225 | foldingFunction (x:y:ys) "^" = (y ** x):ys 226 | foldingFunction (x:xs) "ln" = log x:xs 227 | foldingFunction xs "sum" = [sum xs] 228 | foldingFunction xs numberString = read numberString:xs 229 | ~~~~ 230 | 231 | Wow, great! `/` is division of course and `**` is floating point 232 | exponentiation. With the logarithm operator, we just pattern match 233 | against a single element and the rest of the stack because we only need 234 | one element to perform its natural logarithm. With the sum operator, we 235 | just return a stack that has only one element, which is the sum of the 236 | stack so far. 237 | 238 | ~~~~ {.haskell:hs name="code"} 239 | ghci> solveRPN "2.7 ln" 240 | 0.9932518 241 | ghci> solveRPN "10 10 10 10 sum 4 /" 242 | 10.0 243 | ghci> solveRPN "10 10 10 10 10 sum 4 /" 244 | 12.5 245 | ghci> solveRPN "10 2 ^" 246 | 100.0 247 | ~~~~ 248 | 249 | Notice that we can include floating point numbers in our expression 250 | because `read` knows how to read them. 251 | 252 | ~~~~ {.haskell:hs name="code"} 253 | ghci> solveRPN "43.2425 0.5 ^" 254 | 6.575903 255 | ~~~~ 256 | 257 | I think that making a function that can calculate arbitrary floating 258 | point RPN expressions and has the option to be easily extended in 10 259 | lines is pretty awesome. 260 | 261 | One thing to note about this function is that it's not really fault 262 | tolerant. When given input that doesn't make sense, it will just crash 263 | everything. We'll make a fault tolerant version of this with a type 264 | declaration of `solveRPN :: String -> Maybe Float` once we get to know 265 | monads (they're not scary, trust me!). We could make one right now, but 266 | it would be a bit tedious because it would involve a lot of checking for 267 | `Nothing` on every step. If you're feeling up to the challenge though, you 268 | can go ahead and try it! Hint: you can use `reads` to see if a read was 269 | successful or not. 270 | 271 | Heathrow to London 272 | ------------------ 273 | 274 | Our next problem is this: your plane has just landed in England and you 275 | rent a car. You have a meeting really soon and you have to get from 276 | Heathrow Airport to London as fast as you can (but safely!). 277 | 278 | There are two main roads going from Heathrow to London and there's a 279 | number of regional roads crossing them. It takes you a fixed amount of 280 | time to travel from one crossroads to another. It's up to you to find 281 | the optimal path to take so that you get to London as fast as you can! 282 | You start on the left side and can either cross to the other main road 283 | or go forward. 284 | 285 | ![Heathrow - London](img/roads.png) 286 | 287 | As you can see in the picture, the shortest path from Heathrow to London 288 | in this case is to start on main road B, cross over, go forward on A, 289 | cross over again and then go forward twice on B. If we take this path, 290 | it takes us 75 minutes. Had we chosen any other path, it would take more 291 | than that. 292 | 293 | Our job is to make a program that takes input that represents a road 294 | system and print out what the shortest path across it is. Here's what 295 | the input would look like for this case: 296 | 297 | ~~~~ {.plain name="code"} 298 | 50 299 | 10 300 | 30 301 | 5 302 | 90 303 | 20 304 | 40 305 | 2 306 | 25 307 | 10 308 | 8 309 | 0 310 | ~~~~ 311 | 312 | To mentally parse the input file, read it in threes and mentally split 313 | the road system into sections. Each section is comprised of a road A, 314 | road B and a crossing road. To have it neatly fit into threes, we say 315 | that there's a last crossing section that takes 0 minutes to drive over. 316 | That's because we don't care where we arrive in London, as long as we're 317 | in London. 318 | 319 | Just like we did when solving the RPN calculator problem, we're going to 320 | solve this problem in three steps: 321 | 322 | - Forget Haskell for a minute and think about how we'd solve the 323 | problem by hand 324 | - Think about how we're going to represent our data in Haskell 325 | - Figure out how to operate on that data in Haskell so that we produce 326 | at a solution 327 | 328 | In the RPN calculator section, we first figured out that when 329 | calculating an expression by hand, we'd keep a sort of stack in our 330 | minds and then go over the expression one item at a time. We decided to 331 | use a list of strings to represent our expression. Finally, we used a 332 | left fold to walk over the list of strings while keeping a stack to 333 | produce a solution. 334 | 335 | Okay, so how would we figure out the shortest path from Heathrow to 336 | London by hand? Well, we can just sort of look at the whole picture and 337 | try to guess what the shortest path is and hopefully we'll make a guess 338 | that's right. That solution works for very small inputs, but what if we 339 | have a road that has 10,000 sections? Yikes! We also won't be able to 340 | say for certain that our solution is the optimal one, we can just sort 341 | of say that we're pretty sure. 342 | 343 | That's not a good solution then. Here's a simplified picture of our road 344 | system: 345 | 346 | ![roads](img/roads_simple.png) 347 | 348 | Alright, can you figure out what the shortest path to the first 349 | crossroads (the first blue dot on A, marked *A1*) on road A is? That's 350 | pretty trivial. We just see if it's shorter to go directly forward on A 351 | or if it's shorter to go forward on B and then cross over. Obviously, 352 | it's cheaper to go forward via B and then cross over because that takes 353 | 40 minutes, whereas going directly via A takes 50 minutes. What about 354 | crossroads *B1*? Same thing. We see that it's a lot cheaper to just go 355 | directly via B (incurring a cost of 10 minutes), because going via A and 356 | then crossing over would take us a whole 80 minutes! 357 | 358 | Now we know what the cheapest path to *A1* is (go via B and then cross 359 | over, so we'll say that's `B, C` with a cost of 40) and we know what the 360 | cheapest path to *B1* is (go directly via B, so that's just `B`, going at 361 | 10). Does this knowledge help us at all if we want to know the cheapest 362 | path to the next crossroads on both main roads? Gee golly, it sure does! 363 | 364 | Let's see what the shortest path to *A2* would be. To get to *A2*, we'll 365 | either go directly to *A2* from *A1* or we'll go forward from *B1* and 366 | then cross over (remember, we can only move forward or cross to the 367 | other side). And because we know the cost to *A1* and *B1*, we can 368 | easily figure out what the best path to *A2* is. It costs 40 to get to 369 | *A1* and then 5 to get from *A1* to *A2*, so that's `B, C, A` for a cost 370 | of 45. It costs only 10 to get to *B1*, but then it would take an 371 | additional 110 minutes to go to *B2* and then cross over! So obviously, 372 | the cheapest path to *A2* is `B, C, A`. In the same way, the cheapest way 373 | to *B2* is to go forward from *A1* and then cross over. 374 | 375 | > *Maybe you're asking yourself*: but what about getting to *A2* by first 376 | > crossing over at *B1* and then going on forward? Well, we already 377 | > covered crossing from *B1* to *A1* when we were looking for the best way 378 | > to *A1*, so we don't have to take that into account in the next step as 379 | > well. 380 | 381 | Now that we have the best path to *A2* and *B2*, we can repeat this 382 | indefinitely until we reach the end. Once we've gotten the best paths 383 | for *A4* and *B4*, the one that's cheaper is the optimal path! 384 | 385 | So in essence, for the second section, we just repeat the step we did at 386 | first, only we take into account what the previous best paths on A and 387 | B. We could say that we also took into account the best paths on A and 388 | on B in the first step, only they were both empty paths with a cost of 389 | 0. 390 | 391 | Here's a summary. To get the best path from Heathrow to London, we do 392 | this: first we see what the best path to the next crossroads on main 393 | road A is. The two options are going directly forward or starting at the 394 | opposite road, going forward and then crossing over. We remember the 395 | cost and the path. We use the same method to see what the best path to 396 | the next crossroads on main road B is and remember that. Then, we see if 397 | the path to the next crossroads on A is cheaper if we go from the 398 | previous A crossroads or if we go from the previous B crossroads and 399 | then cross over. We remember the cheaper path and then we do the same 400 | for the crossroads opposite of it. We do this for every section until we 401 | reach the end. Once we've reached the end, the cheapest of the two paths 402 | that we have is our optimal path! 403 | 404 | So in essence, we keep one shortest path on the A road and one shortest 405 | path on the B road and when we reach the end, the shorter of those two 406 | is our path. We now know how to figure out the shortest path by hand. If 407 | you had enough time, paper and pencils, you could figure out the 408 | shortest path through a road system with any number of sections. 409 | 410 | Next step! How do we represent this road system with Haskell's data 411 | types? One way is to think of the starting points and crossroads as 412 | nodes of a graph that point to other crossroads. If we imagine that the 413 | starting points actually point to each other with a road that has a 414 | length of one, we see that every crossroads (or node) points to the node 415 | on the other side and also to the next one on its side. Except for the 416 | last nodes, they just point to the other side. 417 | 418 | ~~~~ {.haskell:hs name="code"} 419 | data Node = Node Road Road | EndNode Road 420 | data Road = Road Int Node 421 | ~~~~ 422 | 423 | A node is either a normal node and has information about the road that 424 | leads to the other main road and the road that leads to the next node or 425 | an end node, which only has information about the road to the other main 426 | road. A road keeps information about how long it is and which node it 427 | points to. For instance, the first part of the road on the A main road 428 | would be `Road 50 a1` where `a1` would be a node `Node x y`, where `x` and `y` are 429 | roads that point to *B1* and *A2*. 430 | 431 | Another way would be to use `Maybe` for the road parts that point forward. 432 | Each node has a road part that point to the opposite road, but only 433 | those nodes that aren't the end ones have road parts that point forward. 434 | 435 | ~~~~ {.haskell:hs name="code"} 436 | data Node = Node Road (Maybe Road) 437 | data Road = Road Int Node 438 | ~~~~ 439 | 440 | This is an alright way to represent the road system in Haskell and we 441 | could certainly solve this problem with it, but maybe we could come up 442 | with something simpler? If we think back to our solution by hand, we 443 | always just checked the lengths of three road parts at once: the road 444 | part on the A road, its opposite part on the B road and part C, which 445 | touches those two parts and connects them. When we were looking for the 446 | shortest path to *A1* and *B1*, we only had to deal with the lengths of 447 | the first three parts, which have lengths of 50, 10 and 30. We'll call 448 | that one section. So the road system that we use for this example can be 449 | easily represented as four sections: `50, 10, 30`, `5, 90, 20`, `40, 2, 25`, 450 | and `10, 8, 0`. 451 | 452 | It's always good to keep our data types as simple as possible, although 453 | not any simpler! 454 | 455 | ~~~~ {.haskell:hs name="code"} 456 | data Section = Section { getA :: Int, getB :: Int, getC :: Int } deriving (Show) 457 | type RoadSystem = [Section] 458 | ~~~~ 459 | 460 | This is pretty much perfect! It's as simple as it goes and I have a 461 | feeling it'll work perfectly for implementing our solution. `Section` is a 462 | simple algebraic data type that holds three integers for the lengths of 463 | its three road parts. We introduce a type synonym as well, saying that 464 | `RoadSystem` is a list of sections. 465 | 466 | > We could also use a triple of `(Int, Int, Int)` to represent a road 467 | > section. Using tuples instead of making your own algebraic data types is 468 | > good for some small localized stuff, but it's usually better to make a 469 | > new type for things like this. It gives the type system more information 470 | > about what's what. We can use `(Int, Int, Int)` to represent a road 471 | > section or a vector in 3D space and we can operate on those two, but 472 | > that allows us to mix them up. If we use `Section` and `Vector` data types, 473 | > then we can't accidentally add a vector to a section of a road system. 474 | 475 | Our road system from Heathrow to London can now be represented like 476 | this: 477 | 478 | ~~~~ {.haskell:hs name="code"} 479 | heathrowToLondon :: RoadSystem 480 | heathrowToLondon = [Section 50 10 30, Section 5 90 20, Section 40 2 25, Section 10 8 0] 481 | ~~~~ 482 | 483 | All we need to do now is to implement the solution that we came up with 484 | previously in Haskell. What should the type declaration for a function 485 | that calculates a shortest path for any given road system be? It should 486 | take a road system as a parameter and return a path. We'll represent a 487 | path as a list as well. Let's introduce a `Label` type that's just an 488 | enumeration of either `A`, `B` or `C`. We'll also make a type synonym: `Path`. 489 | 490 | ~~~~ {.haskell:hs name="code"} 491 | data Label = A | B | C deriving (Show) 492 | type Path = [(Label, Int)] 493 | ~~~~ 494 | 495 | Our function, we'll call it `optimalPath` should thus have a type 496 | declaration of `optimalPath :: RoadSystem -> Path`. If called with the 497 | road system `heathrowToLondon`, it should return the following path: 498 | 499 | ~~~~ {.haskell:hs name="code"} 500 | [(B,10),(C,30),(A,5),(C,20),(B,2),(B,8)] 501 | ~~~~ 502 | 503 | We're going to have to walk over the list with the sections from left to 504 | right and keep the optimal path on A and optimal path on B as we go 505 | along. We'll accumulate the best path as we walk over the list, left to 506 | right. What does that sound like? Ding, ding, ding! That's right, A LEFT 507 | FOLD! 508 | 509 | When doing the solution by hand, there was a step that we repeated over 510 | and over again. It involved checking the optimal paths on A and B so far 511 | and the current section to produce the new optimal paths on A and B. For 512 | instance, at the beginning the optimal paths were `[]` and `[]` for A and B 513 | respectively. We examined the section `Section 50 10 30` and concluded 514 | that the new optimal path to *A1* is `[(B,10),(C,30)]` and the optimal 515 | path to *B1* is `[(B,10)]`. If you look at this step as a function, it 516 | takes a pair of paths and a section and produces a new pair of paths. 517 | The type is `(Path, Path) -> Section -> (Path, Path)`. Let's go ahead 518 | and implement this function, because it's bound to be useful. 519 | 520 | > *Hint:* it will be useful because 521 | > `(Path, Path) -> Section -> (Path, Path)` 522 | > can be used as the binary function for a left fold, which has to 523 | > have a type of `a -> b -> a` 524 | 525 | ~~~~ {.haskell:hs name="code"} 526 | roadStep :: (Path, Path) -> Section -> (Path, Path) 527 | roadStep (pathA, pathB) (Section a b c) = 528 | let priceA = sum $ map snd pathA 529 | priceB = sum $ map snd pathB 530 | forwardPriceToA = priceA + a 531 | crossPriceToA = priceB + b + c 532 | forwardPriceToB = priceB + b 533 | crossPriceToB = priceA + a + c 534 | newPathToA = if forwardPriceToA <= crossPriceToA 535 | then (A,a):pathA 536 | else (C,c):(B,b):pathB 537 | newPathToB = if forwardPriceToB <= crossPriceToB 538 | then (B,b):pathB 539 | else (C,c):(A,a):pathA 540 | in (newPathToA, newPathToB) 541 | ~~~~ 542 | 543 | ![this is you](img/guycar.png) 544 | 545 | What's going on here? First, calculate the optimal price on road A based 546 | on the best so far on A and we do the same for B. We do 547 | `sum $ map snd pathA`, so if `pathA` is something like 548 | `[(A,100),(C,20)]`, `priceA` becomes 549 | `120`. `forwardPriceToA` is the price that we would pay if we went to the 550 | next crossroads on A if we went there directly from the previous 551 | crossroads on A. It equals the best price to our previous A, plus the 552 | length of the A part of the current section. `crossPriceToA` is the price 553 | that we would pay if we went to the next A by going forward from the 554 | previous B and then crossing over. It's the best price to the previous B 555 | so far plus the B length of the section plus the C length of the 556 | section. We determine `forwardPriceToB` and `crossPriceToB` in the same 557 | manner. 558 | 559 | Now that we know what the best way to A and B is, we just need to make 560 | the new paths to A and B based on that. If it's cheaper to go to A by 561 | just going forwards, we set `newPathToA` to be `(A,a):pathA`. Basically we 562 | prepend the `Label` `A` and the section length `a` to the optimal path path on 563 | A so far. Basically, we say that the best path to the next A crossroads 564 | is the path to the previous A crossroads and then one section forward 565 | via A. Remember, `A` is just a label, whereas `a` has a type of `Int`. Why do 566 | we prepend instead of doing `pathA ++ [(A,a)]`? Well, adding an element to 567 | the beginning of a list (also known as consing) is much faster than 568 | adding it to the end. This means that the path will be the wrong way 569 | around once we fold over a list with this function, but it's easy to 570 | reverse the list later. If it's cheaper to get to the next A crossroads 571 | by going forward from road B and then crossing over, then `newPathToA` is 572 | the old path to B that then goes forward and crosses to A. We do the 573 | same thing for `newPathToB`, only everything's mirrored. 574 | 575 | Finally, we return `newPathToA` and `newPathToB` in a pair. 576 | 577 | Let's run this function on the first section of `heathrowToLondon`. 578 | Because it's the first section, the best paths on A and B parameter will 579 | be a pair of empty lists. 580 | 581 | ~~~~ {.haskell:hs name="code"} 582 | ghci> roadStep ([], []) (head heathrowToLondon) 583 | ([(C,30),(B,10)],[(B,10)]) 584 | ~~~~ 585 | 586 | Remember, the paths are reversed, so read them from right to left. From 587 | this we can read that the best path to the next A is to start on B and 588 | then cross over to A and that the best path to the next B is to just go 589 | directly forward from the starting point at B. 590 | 591 | > *Optimization tip:* when we do `priceA = sum $ map snd pathA`, we're 592 | > calculating the price from the path on every step. We wouldn't have to 593 | > do that if we implemented `roadStep` as a 594 | > `(Path, Path, Int, Int) -> Section -> (Path, Path, Int, Int)` 595 | > function where the integers represent 596 | > the best price on A and B. 597 | 598 | Now that we have a function that takes a pair of paths and a section and 599 | produces a new optimal path, we can just easily do a left fold over a 600 | list of sections. `roadStep` is called with `([],[])` and the first section 601 | and returns a pair of optimal paths to that section. Then, it's called 602 | with that pair of paths and the next section and so on. When we've 603 | walked over all the sections, we're left with a pair of optimal paths 604 | and the shorter of them is our answer. With this in mind, we can 605 | implement `optimalPath`. 606 | 607 | ~~~~ {.haskell:hs name="code"} 608 | optimalPath :: RoadSystem -> Path 609 | optimalPath roadSystem = 610 | let (bestAPath, bestBPath) = foldl roadStep ([],[]) roadSystem 611 | in if sum (map snd bestAPath) <= sum (map snd bestBPath) 612 | then reverse bestAPath 613 | else reverse bestBPath 614 | ~~~~ 615 | 616 | We left fold over `roadSystem` (remember, it's a list of sections) with 617 | the starting accumulator being a pair of empty paths. The result of that 618 | fold is a pair of paths, so we pattern match on the pair to get the 619 | paths themselves. Then, we check which one of these was cheaper and 620 | return it. Before returning it, we also reverse it, because the optimal 621 | paths so far were reversed due to us choosing consing over appending. 622 | 623 | Let's test this! 624 | 625 | ~~~~ {.haskell:hs name="code"} 626 | ghci> optimalPath heathrowToLondon 627 | [(B,10),(C,30),(A,5),(C,20),(B,2),(B,8),(C,0)] 628 | ~~~~ 629 | 630 | This is the result that we were supposed to get! Awesome! It differs 631 | from our expected result a bit because there's a step `(C,0)` at the end, 632 | which means that we cross over to the other road once we're in London, 633 | but because that crossing doesn't cost anything, this is still the 634 | correct result. 635 | 636 | We have the function that finds an optimal path based on, now we just 637 | have to read a textual representation of a road system from the standard 638 | input, convert it into a type of `RoadSystem`, run that through our 639 | `optimalPath` function and print the path. 640 | 641 | First off, let's make a function that takes a list and splits it into 642 | groups of the same size. We'll call it `groupsOf`. For a parameter of 643 | `[1..10]`, `groupsOf 3` should return `[[1,2,3],[4,5,6],[7,8,9],[10]]`. 644 | 645 | ~~~~ {.haskell:hs name="code"} 646 | groupsOf :: Int -> [a] -> [[a]] 647 | groupsOf 0 _ = undefined 648 | groupsOf _ [] = [] 649 | groupsOf n xs = take n xs : groupsOf n (drop n xs) 650 | ~~~~ 651 | 652 | A standard recursive function. For an `xs` of `[1..10]` and an `n` of `3`, this 653 | equals `[1,2,3] : groupsOf 3 [4,5,6,7,8,9,10]`. When the recursion is 654 | done, we get our list in groups of three. And here's our `main` function, 655 | which reads from the standard input, makes a `RoadSystem` out of it and 656 | prints out the shortest path: 657 | 658 | ~~~~ {.haskell:hs name="code"} 659 | import Data.List 660 | 661 | main = do 662 | contents <- getContents 663 | let threes = groupsOf 3 (map read $ lines contents) 664 | roadSystem = map (\[a,b,c] -> Section a b c) threes 665 | path = optimalPath roadSystem 666 | pathString = concat $ map (show . fst) path 667 | pathPrice = sum $ map snd path 668 | putStrLn $ "The best path to take is: " ++ pathString 669 | putStrLn $ "The price is: " ++ show pathPrice 670 | ~~~~ 671 | 672 | First, we get all the contents from the standard input. Then, we call 673 | `lines` with our contents to convert something like `"50\n10\n30\n...` to 674 | `["50","10","30"..` and then we map `read` to that to convert it to a list 675 | of numbers. We call `groupsOf 3` on it so that we turn it to a list of 676 | lists of length 3. We map the lambda (`\[a,b,c] -> Section a b c`) over 677 | that list of lists. As you can see, the lambda just takes a list of 678 | length 3 and turns it into a section. So `roadSystem` is now our system of 679 | roads and it even has the correct type, namely `RoadSystem` (or 680 | `[Section]`). We call `optimalPath` with that and then get the path and the 681 | price in a nice textual representation and print it out. 682 | 683 | We save the following text 684 | 685 | ~~~~ {.plain name="code"} 686 | 50 687 | 10 688 | 30 689 | 5 690 | 90 691 | 20 692 | 40 693 | 2 694 | 25 695 | 10 696 | 8 697 | 0 698 | ~~~~ 699 | 700 | in a file called `paths.txt` and then feed it to our program. 701 | 702 | ~~~~ {.plain name="code"} 703 | $ cat paths.txt | runhaskell heathrow.hs 704 | The best path to take is: BCACBBC 705 | The price is: 75 706 | ~~~~ 707 | 708 | Works like a charm! You can use your knowledge of the `Data.Random` module 709 | to generate a much longer system of roads, which you can then feed to 710 | what we just wrote. If you get stack overflows, try using `foldl'` instead 711 | of `foldl`, because `foldl'` is strict. 712 | -------------------------------------------------------------------------------- /en/14-zippers.md: -------------------------------------------------------------------------------- 1 | Zippers 2 | ======= 3 | 4 | ![hi im chet](img/60sdude.png) 5 | 6 | While Haskell's purity comes with a whole bunch of benefits, it makes us 7 | tackle some problems differently than we would in impure languages. 8 | Because of referential transparency, one value is as good as another in 9 | Haskell if it represents the same thing. 10 | 11 | So if we have a tree full of fives (high-fives, maybe?) and we want to 12 | change one of them into a six, we have to have some way of knowing 13 | exactly which five in our tree we want to change. We have to know where 14 | it is in our tree. In impure languages, we could just note where in our 15 | memory the five is located and change that. But in Haskell, one five is 16 | as good as another, so we can't discriminate based on where in our 17 | memory they are. We also can't really *change* anything; when we say 18 | that we change a tree, we actually mean that we take a tree and return a 19 | new one that's similar to the original tree, but slightly different. 20 | 21 | One thing we can do is to remember a path from the root of the tree to 22 | the element that we want to change. We could say, take this tree, go 23 | left, go right and then left again and change the element that's there. 24 | While this works, it can be inefficient. If we want to later change an 25 | element that's near the element that we previously changed, we have to 26 | walk all the way from the root of the tree to our element again! 27 | 28 | In this chapter, we'll see how we can take some data structure and focus 29 | on a part of it in a way that makes changing its elements easy and 30 | walking around it efficient. Nice! 31 | 32 | Taking a walk 33 | ------------- 34 | 35 | Like we've learned in biology class, there are many different kinds of 36 | trees, so let's pick a seed that we will use to plant ours. Here it is: 37 | 38 | ~~~~ {.haskell:hs name="code"} 39 | data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Show) 40 | ~~~~ 41 | 42 | So our tree is either empty or it's a node that has an element and two 43 | sub-trees. Here's a fine example of such a tree, which I give to you, 44 | the reader, for free! 45 | 46 | ~~~~ {.haskell:hs name="code"} 47 | freeTree :: Tree Char 48 | freeTree = 49 | Node 'P' 50 | (Node 'O' 51 | (Node 'L' 52 | (Node 'N' Empty Empty) 53 | (Node 'T' Empty Empty) 54 | ) 55 | (Node 'Y' 56 | (Node 'S' Empty Empty) 57 | (Node 'A' Empty Empty) 58 | ) 59 | ) 60 | (Node 'L' 61 | (Node 'W' 62 | (Node 'C' Empty Empty) 63 | (Node 'R' Empty Empty) 64 | ) 65 | (Node 'A' 66 | (Node 'A' Empty Empty) 67 | (Node 'C' Empty Empty) 68 | ) 69 | ) 70 | ~~~~ 71 | 72 | And here's this tree represented graphically: 73 | 74 | ![polly says her back hurts](img/pollywantsa.png) 75 | 76 | Notice that `W` in the tree there? Say we want to change it into a `P`. How 77 | would we go about doing that? Well, one way would be to pattern match on 78 | our tree until we find the element that's located by first going right 79 | and then left and changing said element. Here's the code for this: 80 | 81 | ~~~~ {.haskell:hs name="code"} 82 | changeToP :: Tree Char -> Tree Char 83 | changeToP (Node x l (Node y (Node _ m n) r)) = Node x l (Node y (Node 'P' m n) r) 84 | ~~~~ 85 | 86 | Yuck! Not only is this rather ugly, it's also kind of confusing. What 87 | happens here? Well, we pattern match on our tree and name its root 88 | element `x` (that's becomes the `'P'` in the root) and its left sub-tree `l`. 89 | Instead of giving a name to its right sub-tree, we further pattern match 90 | on it. We continue this pattern matching until we reach the sub-tree 91 | whose root is our `'W'`. Once we've done this, we rebuild the tree, only 92 | the sub-tree that contained the 'W' at its root now has a `'P'`. 93 | 94 | Is there a better way of doing this? How about we make our function take 95 | a tree along with a list of directions. The directions will be either `L` 96 | or `R`, representing left and right respectively, and we'll change the 97 | element that we arrive at if we follow the supplied directions. Here it 98 | is: 99 | 100 | ~~~~ {.haskell:hs name="code"} 101 | data Direction = L | R deriving (Show) 102 | type Directions = [Direction] 103 | 104 | changeToP :: Directions-> Tree Char -> Tree Char 105 | changeToP (L:ds) (Node x l r) = Node x (changeToP ds l) r 106 | changeToP (R:ds) (Node x l r) = Node x l (changeToP ds r) 107 | changeToP [] (Node _ l r) = Node 'P' l r 108 | ~~~~ 109 | 110 | If the first element in the our list of directions is `L`, we construct a 111 | new tree that's like the old tree, only its left sub-tree has an element 112 | changed to `'P'`. When we recursively call `changeToP`, we give it only the 113 | tail of the list of directions, because we already took a left. We do 114 | the same thing in the case of an `R`. If the list of directions is empty, 115 | that means that we're at our destination, so we return a tree that's 116 | like the one supplied, only it has `'P'` as its root element. 117 | 118 | To avoid printing out the whole tree, let's make a function that takes a 119 | list of directions and tells us what the element at the destination is: 120 | 121 | ~~~~ {.haskell:hs name="code"} 122 | elemAt :: Directions -> Tree a -> a 123 | elemAt (L:ds) (Node _ l _) = elemAt ds l 124 | elemAt (R:ds) (Node _ _ r) = elemAt ds r 125 | elemAt [] (Node x _ _) = x 126 | ~~~~ 127 | 128 | This function is actually quite similar to `changeToP`, only instead of 129 | remembering stuff along the way and reconstructing the tree, it ignores 130 | everything except its destination. Here we change the `'W'` to a `'P'` and 131 | see if the change in our new tree sticks: 132 | 133 | ~~~~ {.haskell:hs name="code"} 134 | ghci> let newTree = changeToP [R,L] freeTree 135 | ghci> elemAt [R,L] newTree 136 | 'P' 137 | ~~~~ 138 | 139 | Nice, this seems to work. In these functions, the list of directions 140 | acts as a sort of *focus*, because it pinpoints one exact sub-tree from 141 | our tree. A direction list of `[R]` focuses on the sub-tree that's right 142 | of the root, for example. An empty direction list focuses on the main 143 | tree itself. 144 | 145 | While this technique may seem cool, it can be rather inefficient, 146 | especially if we want to repeatedly change elements. Say we have a 147 | really huge tree and a long direction list that points to some element 148 | all the way at the bottom of the tree. We use the direction list to take 149 | a walk along the tree and change an element at the bottom. If we want to 150 | change another element that's close to the element that we've just 151 | changed, we have to start from the root of the tree and walk all the way 152 | to the bottom again! What a drag. 153 | 154 | In the next section, we'll find a better way of focusing on a sub-tree, 155 | one that allows us to efficiently switch focus to sub-trees that are 156 | nearby. 157 | 158 | A trail of breadcrumbs 159 | ---------------------- 160 | 161 | ![whoop dee doo](img/bread.png) 162 | 163 | Okay, so for focusing on a sub-tree, we want something better than just 164 | a list of directions that we always follow from the root of our tree. 165 | Would it help if we start at the root of the tree and move either left 166 | or right one step at a time and sort of leave breadcrumbs? That is, when 167 | we go left, we remember that we went left and when we go right, we 168 | remember that we went right. Sure, we can try that. 169 | 170 | To represent our breadcrumbs, we'll also use a list of `Direction` (which 171 | is either `L` or `R`), only instead of calling it `Directions`, we'll call it 172 | `Breadcrumbs` , because our directions will now be reversed since we're 173 | leaving them as we go down our tree: 174 | 175 | ~~~~ {.haskell:hs name="code"} 176 | type Breadcrumbs = [Direction] 177 | ~~~~ 178 | 179 | Here's a function that takes a tree and some breadcrumbs and moves to 180 | the left sub-tree while adding `L` to the head of the list that represents 181 | our breadcrumbs: 182 | 183 | ~~~~ {.haskell:hs name="code"} 184 | goLeft :: (Tree a, Breadcrumbs) -> (Tree a, Breadcrumbs) 185 | goLeft (Node _ l _, bs) = (l, L:bs) 186 | ~~~~ 187 | 188 | We ignore the element at the root and the right sub-tree and just return 189 | the left sub-tree along with the old breadcrumbs with `L` as the head. 190 | Here's a function to go right: 191 | 192 | ~~~~ {.haskell:hs name="code"} 193 | goRight :: (Tree a, Breadcrumbs) -> (Tree a, Breadcrumbs) 194 | goRight (Node _ _ r, bs) = (r, R:bs) 195 | ~~~~ 196 | 197 | It works the same way. Let's use these functions to take our `freeTree` 198 | and go right and then left: 199 | 200 | ~~~~ {.haskell:hs name="code"} 201 | ghci> goLeft (goRight (freeTree, [])) 202 | (Node 'W' (Node 'C' Empty Empty) (Node 'R' Empty Empty),[L,R]) 203 | ~~~~ 204 | 205 | ![almostthere](img/almostzipper.png) 206 | 207 | Okay, so now we have a tree that has `'W'` in its root and `'C'` in the root 208 | of its left sub-tree and `'R'` in the root of its right sub-tree. The 209 | breadcrumbs are `[L,R]`, because we first went right and then left. 210 | 211 | To make walking along our tree clearer, we can use the `-:` function that 212 | we defined like so: 213 | 214 | ~~~~ {.haskell:hs name="code"} 215 | x -: f = f x 216 | ~~~~ 217 | 218 | Which allows us to apply functions to values by first writing the value, 219 | then writing a `-:` and then the function. So instead of 220 | `goRight (freeTree, [])`, we can write `(freeTree, []) -: goRight`. Using this, we 221 | can rewrite the above so that it's more apparent that we're first going 222 | right and then left: 223 | 224 | ~~~~ {.haskell:hs name="code"} 225 | ghci> (freeTree, []) -: goRight -: goLeft 226 | (Node 'W' (Node 'C' Empty Empty) (Node 'R' Empty Empty),[L,R]) 227 | ~~~~ 228 | 229 | ### Going back up 230 | 231 | What if we now want to go back up in our tree? From our breadcrumbs we 232 | know that the current tree is the left sub-tree of its parent and that 233 | it is the right sub-tree of its parent, but that's it. They don't tell 234 | us enough about the parent of the current sub-tree for us to be able to 235 | go up in the tree. It would seem that apart from the direction that we 236 | took, a single breadcrumb should also contain all other data that we 237 | need to go back up. In this case, that's the element in the parent tree 238 | along with its right sub-tree. 239 | 240 | In general, a single breadcrumb should contain all the data needed to 241 | reconstruct the parent node. So it should have the information from all 242 | the paths that we didn't take and it should also know the direction that 243 | we did take, but it must not contain the sub-tree that we're currently 244 | focusing on. That's because we already have that sub-tree in the first 245 | component of the tuple, so if we also had it in the breadcrumbs, we'd 246 | have duplicate information. 247 | 248 | Let's modify our breadcrumbs so that they also contain information about 249 | everything that we previously ignored when moving left and right. 250 | Instead of `Direction`, we'll make a new data type: 251 | 252 | ~~~~ {.haskell:hs name="code"} 253 | data Crumb a = LeftCrumb a (Tree a) | RightCrumb a (Tree a) deriving (Show) 254 | ~~~~ 255 | 256 | Now, instead of just `L`, we have a `LeftCrumb` that also contains the 257 | element in the node that we moved from and the right tree that we didn't 258 | visit. Instead of `R`, we have `RightCrumb`, which contains the element in 259 | the node that we moved from and the left tree that we didn't visit. 260 | 261 | These breadcrumbs now contain all the data needed to recreate the tree 262 | that we walked through. So instead of just being normal bread crumbs, 263 | they're now more like floppy disks that we leave as we go along, because 264 | they contain a lot more information than just the direction that we 265 | took. 266 | 267 | In essence, every breadcrumb is now like a tree node with a hole in it. 268 | When we move deeper into a tree, the breadcrumb carries all the 269 | information that the node that we moved away from carried *except* the 270 | sub-tree that we chose to focus on. It also has to note where the hole 271 | is. In the case of a `LeftCrumb`, we know that we moved left, so the 272 | sub-tree that's missing is the left one. 273 | 274 | Let's also change our `Breadcrumbs` type synonym to reflect this: 275 | 276 | ~~~~ {.haskell:hs name="code"} 277 | type Breadcrumbs a = [Crumb a] 278 | ~~~~ 279 | 280 | Next up, we have to modify the `goLeft` and `goRight` functions to store 281 | information about the paths that we didn't take in our breadcrumbs, 282 | instead of ignoring that information like they did before. Here's 283 | `goLeft`: 284 | 285 | ~~~~ {.haskell:hs name="code"} 286 | goLeft :: (Tree a, Breadcrumbs a) -> (Tree a, Breadcrumbs a) 287 | goLeft (Node x l r, bs) = (l, LeftCrumb x r:bs) 288 | ~~~~ 289 | 290 | You can see that it's very similar to our previous `goLeft`, only instead 291 | of just adding a `L` to the head of our list of breadcrumbs, we add a 292 | `LeftCrumb` to signify that we went left and we equip our `LeftCrumb` with 293 | the element in the node that we moved from (that's the `x`) and the right 294 | sub-tree that we chose not to visit. 295 | 296 | Note that this function assumes that the current tree that's under focus 297 | isn't `Empty`. An empty tree doesn't have any sub-trees, so if we try to 298 | go left from an empty tree, an error will occur because the pattern 299 | match on `Node` won't succeed and there's no pattern that takes care of 300 | `Empty`. 301 | 302 | `goRight` is similar: 303 | 304 | ~~~~ {.haskell:hs name="code"} 305 | goRight :: (Tree a, Breadcrumbs a) -> (Tree a, Breadcrumbs a) 306 | goRight (Node x l r, bs) = (r, RightCrumb x l:bs) 307 | ~~~~ 308 | 309 | We were previously able to go left and right. What we've gotten now is 310 | the ability to actualy go back up by remembering stuff about the parent 311 | nodes and the paths that we didn't visit. Here's the `goUp` function: 312 | 313 | ~~~~ {.haskell:hs name="code"} 314 | goUp :: (Tree a, Breadcrumbs a) -> (Tree a, Breadcrumbs a) 315 | goUp (t, LeftCrumb x r:bs) = (Node x t r, bs) 316 | goUp (t, RightCrumb x l:bs) = (Node x l t, bs) 317 | ~~~~ 318 | 319 | ![asstronaut](img/asstronaut.png) 320 | 321 | We're focusing on the tree `t` and we check what the latest `Crumb` is. If 322 | it's a `LeftCrumb`, then we construct a new tree where our tree `t` is the 323 | left sub-tree and we use the information about the right sub-tree that 324 | we didn't visit and the element to fill out the rest of the `Node`. 325 | Because we moved back so to speak and picked up the last breadcrumb to 326 | recreate with it the parent tree, the new list of breadcrumbs doesn't 327 | contain it. 328 | 329 | Note that this function causes an error if we're already at the top of a 330 | tree and we want to move up. Later on, we'll use the `Maybe` monad to 331 | represent possible failure when moving focus. 332 | 333 | With a pair of `Tree a` and `Breadcrumbs a`, we have all the information to 334 | rebuild the whole tree and we also have a focus on a sub-tree. This 335 | scheme also enables us to easily move up, left and right. Such a pair 336 | that contains a focused part of a data structure and its surroundings is 337 | called a zipper, because moving our focus up and down the data structure 338 | resembles the operation of a zipper on a regular pair of pants. So it's 339 | cool to make a type synonym as such: 340 | 341 | ~~~~ {.haskell:hs name="code"} 342 | type Zipper a = (Tree a, Breadcrumbs a) 343 | ~~~~ 344 | 345 | I'd prefer naming the type synonym `Focus` because that makes it clearer 346 | that we're focusing on a part of a data structure, but the term zipper 347 | is more widely used to describe such a setup, so we'll stick with 348 | `Zipper`. 349 | 350 | ### Manipulating trees under focus 351 | 352 | Now that we can move up and down, let's make a function that modifies 353 | the element in the root of the sub-tree that the zipper is focusing on: 354 | 355 | ~~~~ {.haskell:hs name="code"} 356 | modify :: (a -> a) -> Zipper a -> Zipper a 357 | modify f (Node x l r, bs) = (Node (f x) l r, bs) 358 | modify f (Empty, bs) = (Empty, bs) 359 | ~~~~ 360 | 361 | If we're focusing on a node, we modify its root element with the 362 | function `f`. If we're focusing on an empty tree, we leave it as it is. 363 | Now we can start off with a tree, move to anywhere we want and modify an 364 | element, all while keeping focus on that element so that we can easily 365 | move further up or down. An example: 366 | 367 | ~~~~ {.haskell:hs name="code"} 368 | ghci> let newFocus = modify (\_ -> 'P') (goRight (goLeft (freeTree,[]))) 369 | ~~~~ 370 | 371 | We go left, then right and then modify the root element by replacing it 372 | with a `'P'`. This reads even better if we use `-:`: 373 | 374 | ~~~~ {.haskell:hs name="code"} 375 | ghci> let newFocus = (freeTree,[]) -: goLeft -: goRight -: modify (\_ -> 'P') 376 | ~~~~ 377 | 378 | We can then move up if we want and replace an element with a mysterious 379 | `'X'`: 380 | 381 | ~~~~ {.haskell:hs name="code"} 382 | ghci> let newFocus2 = modify (\_ -> 'X') (goUp newFocus) 383 | ~~~~ 384 | 385 | Or if we wrote it with `-:`: 386 | 387 | ~~~~ {.haskell:hs name="code"} 388 | ghci> let newFocus2 = newFocus -: goUp -: modify (\_ -> 'X') 389 | ~~~~ 390 | 391 | Moving up is easy because the breadcrumbs that we leave form the part of 392 | the data structure that we're not focusing on, but it's inverted, sort 393 | of like turning a sock inside out. That's why when we want to move up, 394 | we don't have to start from the root and make our way down, but we just 395 | take the top of our inverted tree, thereby uninverting a part of it and 396 | adding it to our focus. 397 | 398 | Each node has two sub-trees, even if those sub-trees are empty trees. So 399 | if we're focusing on an empty sub-tree, one thing we can do is to 400 | replace it with a non-empty subtree, thus attaching a tree to a leaf 401 | node. The code for this is simple: 402 | 403 | ~~~~ {.haskell:hs name="code"} 404 | attach :: Tree a -> Zipper a -> Zipper a 405 | attach t (_, bs) = (t, bs) 406 | ~~~~ 407 | 408 | We take a tree and a zipper and return a new zipper that has its focus 409 | replaced with the supplied tree. Not only can we extend trees this way 410 | by replacing empty sub-trees with new trees, we can also replace whole 411 | existing sub-trees. Let's attach a tree to the far left of our `freeTree`: 412 | 413 | ~~~~ {.haskell:hs name="code"} 414 | ghci> let farLeft = (freeTree,[]) -: goLeft -: goLeft -: goLeft -: goLeft 415 | ghci> let newFocus = farLeft -: attach (Node 'Z' Empty Empty) 416 | ~~~~ 417 | 418 | `newFocus` is now focused on the tree that we just attached and the rest 419 | of the tree lies inverted in the breadcrumbs. If we were to use `goUp` to 420 | walk all the way to the top of the tree, it would be the same tree as 421 | `freeTree` but with an additional `'Z'` on its far left. 422 | 423 | ### I'm going straight to the top, oh yeah, up where the air is fresh and clean! 424 | 425 | Making a function that walks all the way to the top of the tree, 426 | regardless of what we're focusing on, is really easy. Here it is: 427 | 428 | ~~~~ {.haskell:hs name="code"} 429 | topMost :: Zipper a -> Zipper a 430 | topMost (t,[]) = (t,[]) 431 | topMost z = topMost (goUp z) 432 | ~~~~ 433 | 434 | If our trail of beefed up breadcrumbs is empty, this means that we're 435 | already at the root of our tree, so we just return the current focus. 436 | Otherwise, we go up to get the focus of the parent node and then 437 | recursively apply `topMost` to that. So now we can walk around our tree, 438 | going left and right and up, applying `modify` and `attach` as we go along 439 | and then when we're done with our modifications, we use `topMost` to focus 440 | on the root of our tree and see the changes that we've done in proper 441 | perspective. 442 | 443 | Focusing on lists 444 | ----------------- 445 | 446 | Zippers can be used with pretty much any data structure, so it's no 447 | surprise that they can be used to focus on sub-lists of lists. After 448 | all, lists are pretty much like trees, only where a node in a tree has 449 | an element (or not) and several sub-trees, a node in a list has an 450 | element and only a single sub-list. When we [implemented our own 451 | lists](#recursive-data-structures), 452 | we defined our data type like so: 453 | 454 | ~~~~ {.haskell:hs name="code"} 455 | data List a = Empty | Cons a (List a) deriving (Show, Read, Eq, Ord) 456 | ~~~~ 457 | 458 | ![the best damn thing](img/picard.png) 459 | 460 | Contrast this with our definition of our binary tree and it's easy to 461 | see how lists can be viewed as trees where each node has only one 462 | sub-tree. 463 | 464 | A list like `[1,2,3]` can be written as `1:2:3:[]`. It consists of the head 465 | of the list, which is `1` and then the list's tail, which is `2:3:[]`. In 466 | turn, `2:3:[]` also has a head, which is `2` and a tail, which is `3:[]`. With 467 | `3:[]`, the `3` is the head and the tail is the empty list `[]`. 468 | 469 | Let's make a zipper for lists. To change the focus on sub-lists of a 470 | list, we move either forward or back (whereas with trees we moved either 471 | up or left or right). The focused part will be a sub-tree and along with 472 | that we'll leave breadcrumbs as we move forward. Now what would a single 473 | breadcrumb for a list consist of? When we were dealing with binary 474 | trees, we said that a breadcrumb has to hold the element in the root of 475 | the parent node along with all the sub-trees that we didn't choose. It 476 | also had to remember if we went left or right. So, it had to have all 477 | the information that a node has except for the sub-tree that we chose to 478 | focus on. 479 | 480 | Lists are simpler than trees, so we don't have to remember if we went 481 | left or right, because there's only one way to go deeper into a list. 482 | Because there's only one sub-tree to each node, we don't have to 483 | remember the paths that we didn't take either. It seems that all we have 484 | to remember is the previous element. If we have a list like `[3,4,5]` and 485 | we know that the previous element was `2`, we can go back by just putting 486 | that element at the head of our list, getting `[2,3,4,5]`. 487 | 488 | Because a single breadcrumb here is just the element, we don't really 489 | have to put it inside a data type, like we did when we made the `Crumb` 490 | data type for tree zippers: 491 | 492 | ~~~~ {.haskell:hs name="code"} 493 | type ListZipper a = ([a],[a]) 494 | ~~~~ 495 | 496 | The first list represents the list that we're focusing on and the second 497 | list is the list of breadcrumbs. Let's make functions that go forward 498 | and back into lists: 499 | 500 | ~~~~ {.haskell:hs name="code"} 501 | goForward :: ListZipper a -> ListZipper a 502 | goForward (x:xs, bs) = (xs, x:bs) 503 | 504 | goBack :: ListZipper a -> ListZipper a 505 | goBack (xs, b:bs) = (b:xs, bs) 506 | ~~~~ 507 | 508 | When we're going forward, we focus on the tail of the current list and 509 | leave the head element as a breadcrumb. When we're moving backwards, we 510 | take the latest breadcrumb and put it at the beginning of the list. 511 | 512 | Here are these two functions in action: 513 | 514 | ~~~~ {.haskell:hs name="code"} 515 | ghci> let xs = [1,2,3,4] 516 | ghci> goForward (xs,[]) 517 | ([2,3,4],[1]) 518 | ghci> goForward ([2,3,4],[1]) 519 | ([3,4],[2,1]) 520 | ghci> goForward ([3,4],[2,1]) 521 | ([4],[3,2,1]) 522 | ghci> goBack ([4],[3,2,1]) 523 | ([3,4],[2,1]) 524 | ~~~~ 525 | 526 | We see that the breadcrumbs in the case of lists are nothing more but a 527 | reversed part of our list. The element that we move away from always 528 | goes into the head of the breadcrumbs, so it's easy to move back by just 529 | taking that element from the head of the breadcrumbs and making it the 530 | head of our focus. 531 | 532 | This also makes it easier to see why we call this a zipper, because this 533 | really looks like the slider of a zipper moving up and down. 534 | 535 | If you were making a text editor, you could use a list of strings to 536 | represent the lines of text that are currently opened and you could then 537 | use a zipper so that you know which line the cursor is currently focused 538 | on. By using a zipper, it would also make it easier to insert new lines 539 | anywhere in the text or delete existing ones. 540 | 541 | A very simple file system 542 | ------------------------- 543 | 544 | Now that we know how zippers work, let's use trees to represent a very 545 | simple file system and then make a zipper for that file system, which 546 | will allow us to move between folders, just like we usually do when 547 | jumping around our file system. 548 | 549 | If we take a simplistic view of the average hierarchical file system, we 550 | see that it's mostly made up of files and folders. Files are units of 551 | data and come with a name, whereas folders are used to organize those 552 | files and can contain files or other folders. So let's say that an item 553 | in a file system is either a file, which comes with a name and some 554 | data, or a folder, which has a name and then a bunch of items that are 555 | either files or folders themselves. Here's a data type for this and some 556 | type synonyms so we know what's what: 557 | 558 | ~~~~ {.haskell:hs name="code"} 559 | type Name = String 560 | type Data = String 561 | data FSItem = File Name Data | Folder Name [FSItem] deriving (Show) 562 | ~~~~ 563 | 564 | A file comes with two strings, which represent its name and the data it 565 | holds. A folder comes with a string that is its name and a list of 566 | items. If that list is empty, then we have an empty folder. 567 | 568 | Here's a folder with some files and sub-folders: 569 | 570 | ~~~~ {.haskell:hs name="code"} 571 | myDisk :: FSItem 572 | myDisk = 573 | Folder "root" 574 | [ File "goat_yelling_like_man.wmv" "baaaaaa" 575 | , File "pope_time.avi" "god bless" 576 | , Folder "pics" 577 | [ File "ape_throwing_up.jpg" "bleargh" 578 | , File "watermelon_smash.gif" "smash!!" 579 | , File "skull_man(scary).bmp" "Yikes!" 580 | ] 581 | , File "dijon_poupon.doc" "best mustard" 582 | , Folder "programs" 583 | [ File "fartwizard.exe" "10gotofart" 584 | , File "owl_bandit.dmg" "mov eax, h00t" 585 | , File "not_a_virus.exe" "really not a virus" 586 | , Folder "source code" 587 | [ File "best_hs_prog.hs" "main = print (fix error)" 588 | , File "random.hs" "main = print 4" 589 | ] 590 | ] 591 | ] 592 | ~~~~ 593 | 594 | That's actually what my disk contains right now. 595 | 596 | ### A zipper for our file system 597 | 598 | ![spongedisk](img/spongedisk.png) 599 | 600 | Now that we have a file system, all we need is a zipper so we can zip 601 | and zoom around it and add, modify and remove files as well as folders. 602 | Like with binary trees and lists, we're going to be leaving breadcrumbs 603 | that contain info about all the stuff that we chose not to visit. Like 604 | we said, a single breadcrumb should be kind of like a node, only it 605 | should contain everything except the sub-tree that we're currently 606 | focusing on. It should also note where the hole is so that once we move 607 | back up, we can plug our previous focus into the hole. 608 | 609 | In this case, a breadcrumb should be like a folder, only it should be 610 | missing the folder that we currently chose. Why not like a file, you 611 | ask? Well, because once we're focusing on a file, we can't move deeper 612 | into the file system, so it doesn't make sense to leave a breadcrumb 613 | that says that we came from a file. A file is sort of like an empty 614 | tree. 615 | 616 | If we're focusing on the folder `"root"` and we then focus on the file 617 | `"dijon_poupon.doc"`, what should the breadcrumb that we leave look like? 618 | Well, it should contain the name of its parent folder along with the 619 | items that come before the file that we're focusing on and the items 620 | that come after it. So all we need is a `Name` and two lists of items. By 621 | keeping separate lists for the items that come before the item that 622 | we're focusing and for the items that come after it, we know exactly 623 | where to place it once we move back up. So this way, we know where the 624 | hole is. 625 | 626 | Here's our breadcrumb type for the file system: 627 | 628 | ~~~~ {.haskell:hs name="code"} 629 | data FSCrumb = FSCrumb Name [FSItem] [FSItem] deriving (Show) 630 | ~~~~ 631 | 632 | And here's a type synonym for our zipper: 633 | 634 | ~~~~ {.haskell:hs name="code"} 635 | type FSZipper = (FSItem, [FSCrumb]) 636 | ~~~~ 637 | 638 | Going back up in the hierarchy is very simple. We just take the latest 639 | breadcrumb and assemble a new focus from the current focus and 640 | breadcrumb. Like so: 641 | 642 | ~~~~ {.haskell:hs name="code"} 643 | fsUp :: FSZipper -> FSZipper 644 | fsUp (item, FSCrumb name ls rs:bs) = (Folder name (ls ++ [item] ++ rs), bs) 645 | ~~~~ 646 | 647 | Because our breadcrumb knew what the parent folder's name was, as well 648 | as the items that came before our focused item in the folder (that's `ls`) 649 | and the ones that came after (that's `rs`), moving up was easy. 650 | 651 | How about going deeper into the file system? If we're in the `"root"` and 652 | we want to focus on `"dijon_poupon.doc"`, the breadcrumb that we leave is 653 | going to include the name `"root"` along with the items that precede 654 | `"dijon_poupon.doc"` and the ones that come after it. 655 | 656 | Here's a function that, given a name, focuses on a file of folder that's 657 | located in the current focused folder: 658 | 659 | ~~~~ {.haskell:hs name="code"} 660 | import Data.List (break) 661 | 662 | fsTo :: Name -> FSZipper -> FSZipper 663 | fsTo name (Folder folderName items, bs) = 664 | let (ls, item:rs) = break (nameIs name) items 665 | in (item, FSCrumb folderName ls rs:bs) 666 | 667 | nameIs :: Name -> FSItem -> Bool 668 | nameIs name (Folder folderName _) = name == folderName 669 | nameIs name (File fileName _) = name == fileName 670 | ~~~~ 671 | 672 | `fsTo` takes a `Name` and a `FSZipper` and returns a new `FSZipper` that focuses 673 | on the file with the given name. That file has to be in the current 674 | focused folder. This function doesn't search all over the place, it just 675 | looks at the current folder. 676 | 677 | ![wow cool great](img/cool.png) 678 | 679 | First we use `break` to break the list of items in a folder into those 680 | that precede the file that we're searching for and those that come after 681 | it. If you remember, `break` takes a predicate and a list and returns a 682 | pair of lists. The first list in the pair holds items for which the 683 | predicate returns `False`. Then, once the predicate returns `True` for an 684 | item, it places that item and the rest of the list in the second item of 685 | the pair. We made an auxiliary function called `nameIs` that takes a name 686 | and a file system item and returns `True` if the names match. 687 | 688 | So now, `ls` is a list that contains the items that precede the `item` that 689 | we're searching for, item is that very item and `rs` is the list of items 690 | that come after it in its folder. Now that we have this, we just present 691 | the item that we got from `break` as the focus and build a breadcrumb that 692 | has all the data it needs. 693 | 694 | Note that if the name we're looking for isn't in the folder, the pattern 695 | `item:rs` will try to match on an empty list and we'll get an error. Also, 696 | if our current focus isn't a folder at all but a file, we get an error 697 | as well and the program crashes. 698 | 699 | Now we can move up and down our file system. Let's start at the root and 700 | walk to the file `"skull_man(scary).bmp"`: 701 | 702 | ~~~~ {.haskell:hs name="code"} 703 | ghci> let newFocus = (myDisk,[]) -: fsTo "pics" -: fsTo "skull_man(scary).bmp" 704 | ~~~~ 705 | 706 | `newFocus` is now a zipper that's focused on the `"skull_man(scary).bmp"` 707 | file. Let's get the first component of the zipper (the focus itself) and 708 | see if that's really true: 709 | 710 | ~~~~ {.haskell:hs name="code"} 711 | ghci> fst newFocus 712 | File "skull_man(scary).bmp" "Yikes!" 713 | ~~~~ 714 | 715 | Let's move up and then focus on its neighboring file 716 | `"watermelon_smash.gif"`: 717 | 718 | ~~~~ {.haskell:hs name="code"} 719 | ghci> let newFocus2 = newFocus -: fsUp -: fsTo "watermelon_smash.gif" 720 | ghci> fst newFocus2 721 | File "watermelon_smash.gif" "smash!!" 722 | ~~~~ 723 | 724 | ### Manipulating our file system 725 | 726 | Now that we know how to navigate our file system, manipulating it is 727 | easy. Here's a function that renames the currently focused file or 728 | folder: 729 | 730 | ~~~~ {.haskell:hs name="code"} 731 | fsRename :: Name -> FSZipper -> FSZipper 732 | fsRename newName (Folder name items, bs) = (Folder newName items, bs) 733 | fsRename newName (File name dat, bs) = (File newName dat, bs) 734 | ~~~~ 735 | 736 | Now we can rename our `"pics"` folder to `"cspi"`: 737 | 738 | ~~~~ {.haskell:hs name="code"} 739 | ghci> let newFocus = (myDisk,[]) -: fsTo "pics" -: fsRename "cspi" -: fsUp 740 | ~~~~ 741 | 742 | We descended to the `"pics"` folder, renamed it and then moved back up. 743 | 744 | How about a function that makes a new item in the current folder? 745 | Behold: 746 | 747 | ~~~~ {.haskell:hs name="code"} 748 | fsNewFile :: FSItem -> FSZipper -> FSZipper 749 | fsNewFile item (Folder folderName items, bs) = 750 | (Folder folderName (item:items), bs) 751 | ~~~~ 752 | 753 | Easy as pie. Note that this would crash if we tried to add an item but 754 | weren't focusing on a folder, but were focusing on a file instead. 755 | 756 | Let's add a file to our `"pics"` folder and then move back up to the root: 757 | 758 | ~~~~ {.haskell:hs name="code"} 759 | ghci> let newFocus = (myDisk,[]) -: fsTo "pics" -: fsNewFile (File "heh.jpg" "lol") -: fsUp 760 | ~~~~ 761 | 762 | What's really cool about all this is that when we modify our file 763 | system, it doesn't actually modify it in place but it returns a whole 764 | new file system. That way, we have access to our old file system (in 765 | this case, `myDisk`) as well as the new one (the first component of 766 | `newFocus`). So by using zippers, we get versioning for free, meaning that 767 | we can always refer to older versions of data structures even after 768 | we've changed them, so to speak. This isn't unique to zippers, but is a 769 | property of Haskell because its data structures are immutable. With 770 | zippers however, we get the ability to easily and efficiently walk 771 | around our data structures, so the persistence of Haskell's data 772 | structures really begins to shine. 773 | 774 | Watch your step 775 | --------------- 776 | 777 | So far, while walking through our data structures, whether they were 778 | binary trees, lists or file systems, we didn't really care if we took a 779 | step too far and fell off. For instance, our `goLeft` function takes a 780 | zipper of a binary tree and moves the focus to its left sub-tree: 781 | 782 | ~~~~ {.haskell:hs name="code"} 783 | goLeft :: Zipper a -> Zipper a 784 | goLeft (Node x l r, bs) = (l, LeftCrumb x r:bs) 785 | ~~~~ 786 | 787 | ![falling for you](img/bigtree.png) 788 | 789 | But what if the tree we're stepping off from is an empty tree? That is, 790 | what if it's not a `Node`, but an `Empty`? In this case, we'd get a runtime 791 | error because the pattern match would fail and we have made no pattern 792 | to handle an empty tree, which doesn't have any sub-trees at all. So 793 | far, we just assumed that we'd never try to focus on the left sub-tree 794 | of an empty tree as its left sub-tree doesn't exist at all. But going to 795 | the left sub-tree of an empty tree doesn't make much sense, and so far 796 | we've just conveniently ignored this. 797 | 798 | Or what if we were already at the root of some tree and didn't have any 799 | breadcrumbs but still tried to move up? The same thing would happen. It 800 | seems that when using zippers, any step could be our last (cue ominous 801 | music). In other words, any move can result in a success, but it can 802 | also result in a failure. Does that remind you of something? Of course, 803 | monads! More specifically, the `Maybe` monad which adds a context of 804 | possible failure to normal values. 805 | 806 | So let's use the `Maybe` monad to add a context of possible failure to our 807 | movements. We're going to take the functions that work on our binary 808 | tree zipper and we're going to make them into monadic functions. First, 809 | let's take care of possible failure in `goLeft` and `goRight`. So far, the 810 | failure of functions that could fail was always reflected in their 811 | result, and this time is no different. So here are `goLeft` and `goRight` 812 | with an added possibility of failure: 813 | 814 | ~~~~ {.haskell:hs name="code"} 815 | goLeft :: Zipper a -> Maybe (Zipper a) 816 | goLeft (Node x l r, bs) = Just (l, LeftCrumb x r:bs) 817 | goLeft (Empty, _) = Nothing 818 | 819 | goRight :: Zipper a -> Maybe (Zipper a) 820 | goRight (Node x l r, bs) = Just (r, RightCrumb x l:bs) 821 | goRight (Empty, _) = Nothing 822 | ~~~~ 823 | 824 | Cool, now if we try to take a step to the left of an empty tree, we get 825 | a `Nothing`! 826 | 827 | ~~~~ {.haskell:hs name="code"} 828 | ghci> goLeft (Empty, []) 829 | Nothing 830 | ghci> goLeft (Node 'A' Empty Empty, []) 831 | Just (Empty,[LeftCrumb 'A' Empty]) 832 | ~~~~ 833 | 834 | Looks good! How about going up? The problem before happened if we tried 835 | to go up but we didn't have any more breadcrumbs, which meant that we 836 | were already in the root of the tree. This is the `goUp` function that 837 | throws an error if we don't keep within the bounds of our tree: 838 | 839 | ~~~~ {.haskell:hs name="code"} 840 | goUp :: Zipper a -> Zipper a 841 | goUp (t, LeftCrumb x r:bs) = (Node x t r, bs) 842 | goUp (t, RightCrumb x l:bs) = (Node x l t, bs) 843 | ~~~~ 844 | 845 | Now let's modify it to fail gracefully: 846 | 847 | ~~~~ {.haskell:hs name="code"} 848 | goUp :: Zipper a -> Maybe (Zipper a) 849 | goUp (t, LeftCrumb x r:bs) = Just (Node x t r, bs) 850 | goUp (t, RightCrumb x l:bs) = Just (Node x l t, bs) 851 | goUp (_, []) = Nothing 852 | ~~~~ 853 | 854 | If we have breadcrumbs, everything is okay and we return a successful 855 | new focus, but if we don't, then we return a failure. 856 | 857 | Before, these functions took zippers and returned zippers, which meant 858 | that we could chain them like this to walk around: 859 | 860 | ~~~~ {.haskell:hs name="code"} 861 | gchi> let newFocus = (freeTree,[]) -: goLeft -: goRight 862 | ~~~~ 863 | 864 | But now, instead of returning `Zipper a`, they return `Maybe (Zipper a)`, so 865 | chaining functions like this won't work. We had a similar problem when 866 | we were [dealing with our tightrope 867 | walker](#walk-the-line) in the chapter about monads. 868 | He also walked one step at a time and each of his steps could result in 869 | failure because a bunch of birds could land on one side of his balancing 870 | pole and make him fall. 871 | 872 | Now, the joke's on us because we're the ones doing the walking, and 873 | we're traversing a labyrinth of our own devising. Luckily, we can learn 874 | from the tightrope walker and just do what he did, which is to exchange 875 | normal function application for using `>>=`, which takes a value with a 876 | context (in our case, the `Maybe (Zipper a)`, which has a context of 877 | possible failure) and feeds it into a function while making sure that 878 | the context is taken care of. So just like our tightrope walker, we're 879 | going to trade in all our `-:` operators for `>>=`. Alright, we can chain 880 | our functions again! Watch: 881 | 882 | ~~~~ {.haskell:hs name="code"} 883 | ghci> let coolTree = Node 1 Empty (Node 3 Empty Empty) 884 | ghci> return (coolTree,[]) >>= goRight 885 | Just (Node 3 Empty Empty,[RightCrumb 1 Empty]) 886 | ghci> return (coolTree,[]) >>= goRight >>= goRight 887 | Just (Empty,[RightCrumb 3 Empty,RightCrumb 1 Empty]) 888 | ghci> return (coolTree,[]) >>= goRight >>= goRight >>= goRight 889 | Nothing 890 | ~~~~ 891 | 892 | We used `return` to put a zipper in a `Just` and then used `>>=` to feed 893 | that to our `goRight` function. First, we made a tree that has on its left 894 | an empty sub-tree and on its right a node that has two empty sub-trees. 895 | When we try to go right once, the result is a success, because the 896 | operation makes sense. Going right twice is okay too; we end up with the 897 | focus on an empty sub-tree. But going right three times wouldn't make 898 | sense, because we can't go to the right of an empty sub-tree, which is 899 | why the result is a `Nothing`. 900 | 901 | Now we've equipped our trees with a safety-net that will catch us should 902 | we fall off. Wow, I nailed this metaphor. 903 | 904 | Our file system also has a lot of cases where an operation could fail, 905 | such as trying to focus on a file or folder that doesn't exist. As an 906 | exercise, you can equip our file system with functions that fail 907 | gracefully by using the `Maybe` monad. 908 | -------------------------------------------------------------------------------- /epub-stylesheet.css: -------------------------------------------------------------------------------- 1 | /* This defines styles and classes used in the book */ 2 | code { 3 | font-family: "Ubuntu Mono", monospace; 4 | font-size: 1em; 5 | line-height: 100%; 6 | white-space: pre-wrap; 7 | } 8 | ol.toc { 9 | padding: 0; 10 | margin-left: 1em; 11 | } 12 | ol.toc li { 13 | list-style-type: none; 14 | margin: 0; 15 | padding: 0; 16 | } 17 | pre { 18 | margin: 10pt; 19 | } 20 | #cover img { 21 | width: 100%; 22 | } 23 | @font-face { 24 | font-family: "Ubuntu Mono"; 25 | font-weight: normal; 26 | font-style: normal; 27 | src: url(UbuntuMono-Regular.otf); 28 | } 29 | -------------------------------------------------------------------------------- /img/60sdude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/60sdude.png -------------------------------------------------------------------------------- /img/accordion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/accordion.png -------------------------------------------------------------------------------- /img/alien.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/alien.png -------------------------------------------------------------------------------- /img/almostzipper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/almostzipper.png -------------------------------------------------------------------------------- /img/angeleyes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/angeleyes.png -------------------------------------------------------------------------------- /img/arguments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/arguments.png -------------------------------------------------------------------------------- /img/asstronaut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/asstronaut.png -------------------------------------------------------------------------------- /img/baby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/baby.png -------------------------------------------------------------------------------- /img/badge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/badge.png -------------------------------------------------------------------------------- /img/balloondog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/balloondog.png -------------------------------------------------------------------------------- /img/banana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/banana.png -------------------------------------------------------------------------------- /img/bear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/bear.png -------------------------------------------------------------------------------- /img/bigtree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/bigtree.png -------------------------------------------------------------------------------- /img/binarytree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/binarytree.png -------------------------------------------------------------------------------- /img/bird.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/bird.png -------------------------------------------------------------------------------- /img/boat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/boat.png -------------------------------------------------------------------------------- /img/bomb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/bomb.png -------------------------------------------------------------------------------- /img/bonus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/bonus.png -------------------------------------------------------------------------------- /img/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/box.png -------------------------------------------------------------------------------- /img/brain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/brain.png -------------------------------------------------------------------------------- /img/bread.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/bread.png -------------------------------------------------------------------------------- /img/buddha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/buddha.png -------------------------------------------------------------------------------- /img/cactus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/cactus.png -------------------------------------------------------------------------------- /img/calculator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/calculator.png -------------------------------------------------------------------------------- /img/case.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/case.png -------------------------------------------------------------------------------- /img/caveman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/caveman.png -------------------------------------------------------------------------------- /img/centaur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/centaur.png -------------------------------------------------------------------------------- /img/chainchomp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/chainchomp.png -------------------------------------------------------------------------------- /img/chess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/chess.png -------------------------------------------------------------------------------- /img/chicken.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/chicken.png -------------------------------------------------------------------------------- /img/classes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/classes.png -------------------------------------------------------------------------------- /img/clint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/clint.png -------------------------------------------------------------------------------- /img/composition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/composition.png -------------------------------------------------------------------------------- /img/concatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/concatmap.png -------------------------------------------------------------------------------- /img/cool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/cool.png -------------------------------------------------------------------------------- /img/cow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/cow.png -------------------------------------------------------------------------------- /img/cowboy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/cowboy.png -------------------------------------------------------------------------------- /img/curry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/curry.png -------------------------------------------------------------------------------- /img/deadcat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/deadcat.png -------------------------------------------------------------------------------- /img/dognap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/dognap.png -------------------------------------------------------------------------------- /img/dollar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/dollar.png -------------------------------------------------------------------------------- /img/edd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/edd.png -------------------------------------------------------------------------------- /img/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/file.png -------------------------------------------------------------------------------- /img/foldl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/foldl.png -------------------------------------------------------------------------------- /img/frogtor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/frogtor.png -------------------------------------------------------------------------------- /img/functor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/functor.png -------------------------------------------------------------------------------- /img/fx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/fx.png -------------------------------------------------------------------------------- /img/gob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/gob.png -------------------------------------------------------------------------------- /img/guards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/guards.png -------------------------------------------------------------------------------- /img/guycar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/guycar.png -------------------------------------------------------------------------------- /img/helloworld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/helloworld.png -------------------------------------------------------------------------------- /img/jackofdiamonds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/jackofdiamonds.png -------------------------------------------------------------------------------- /img/jazzb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/jazzb.png -------------------------------------------------------------------------------- /img/judgedog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/judgedog.png -------------------------------------------------------------------------------- /img/justice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/justice.png -------------------------------------------------------------------------------- /img/kermit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/kermit.png -------------------------------------------------------------------------------- /img/kid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/kid.png -------------------------------------------------------------------------------- /img/knight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/knight.png -------------------------------------------------------------------------------- /img/krakatoa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/krakatoa.png -------------------------------------------------------------------------------- /img/lamb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/lamb.png -------------------------------------------------------------------------------- /img/lambda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/lambda.png -------------------------------------------------------------------------------- /img/lazy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/lazy.png -------------------------------------------------------------------------------- /img/legochar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/legochar.png -------------------------------------------------------------------------------- /img/legolists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/legolists.png -------------------------------------------------------------------------------- /img/legomap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/legomap.png -------------------------------------------------------------------------------- /img/legosets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/legosets.png -------------------------------------------------------------------------------- /img/letitbe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/letitbe.png -------------------------------------------------------------------------------- /img/lifter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/lifter.png -------------------------------------------------------------------------------- /img/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/list.png -------------------------------------------------------------------------------- /img/listmonster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/listmonster.png -------------------------------------------------------------------------------- /img/luggage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/luggage.png -------------------------------------------------------------------------------- /img/lyah.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/lyah.jpg -------------------------------------------------------------------------------- /img/making_modules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/making_modules.png -------------------------------------------------------------------------------- /img/maoi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/maoi.png -------------------------------------------------------------------------------- /img/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/map.png -------------------------------------------------------------------------------- /img/maxs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/maxs.png -------------------------------------------------------------------------------- /img/meekrat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/meekrat.png -------------------------------------------------------------------------------- /img/miner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/miner.png -------------------------------------------------------------------------------- /img/modules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/modules.png -------------------------------------------------------------------------------- /img/notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/notes.png -------------------------------------------------------------------------------- /img/origami.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/origami.png -------------------------------------------------------------------------------- /img/owld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/owld.png -------------------------------------------------------------------------------- /img/painter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/painter.png -------------------------------------------------------------------------------- /img/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/pattern.png -------------------------------------------------------------------------------- /img/picard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/picard.png -------------------------------------------------------------------------------- /img/pierre.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/pierre.png -------------------------------------------------------------------------------- /img/pirateship.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/pirateship.png -------------------------------------------------------------------------------- /img/police.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/police.png -------------------------------------------------------------------------------- /img/pollywantsa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/pollywantsa.png -------------------------------------------------------------------------------- /img/present.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/present.png -------------------------------------------------------------------------------- /img/prob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/prob.png -------------------------------------------------------------------------------- /img/puppy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/puppy.png -------------------------------------------------------------------------------- /img/pythag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/pythag.png -------------------------------------------------------------------------------- /img/quickman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/quickman.png -------------------------------------------------------------------------------- /img/quicksort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/quicksort.png -------------------------------------------------------------------------------- /img/random.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/random.png -------------------------------------------------------------------------------- /img/record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/record.png -------------------------------------------------------------------------------- /img/recursion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/recursion.png -------------------------------------------------------------------------------- /img/revolver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/revolver.png -------------------------------------------------------------------------------- /img/ride.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/ride.png -------------------------------------------------------------------------------- /img/ringring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/ringring.png -------------------------------------------------------------------------------- /img/roads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/roads.png -------------------------------------------------------------------------------- /img/roads_simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/roads_simple.png -------------------------------------------------------------------------------- /img/rpn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/rpn.png -------------------------------------------------------------------------------- /img/salad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/salad.png -------------------------------------------------------------------------------- /img/setnotation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/setnotation.png -------------------------------------------------------------------------------- /img/shamrock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/shamrock.png -------------------------------------------------------------------------------- /img/smug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/smug.png -------------------------------------------------------------------------------- /img/smugpig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/smugpig.png -------------------------------------------------------------------------------- /img/spearhead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/spearhead.png -------------------------------------------------------------------------------- /img/spongedisk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/spongedisk.png -------------------------------------------------------------------------------- /img/startingout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/startingout.png -------------------------------------------------------------------------------- /img/streams.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/streams.png -------------------------------------------------------------------------------- /img/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/sun.png -------------------------------------------------------------------------------- /img/texas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/texas.png -------------------------------------------------------------------------------- /img/thefonz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/thefonz.png -------------------------------------------------------------------------------- /img/timber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/timber.png -------------------------------------------------------------------------------- /img/tipi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/tipi.png -------------------------------------------------------------------------------- /img/trafficlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/trafficlight.png -------------------------------------------------------------------------------- /img/tuco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/tuco.png -------------------------------------------------------------------------------- /img/tuple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/tuple.png -------------------------------------------------------------------------------- /img/tur2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/tur2.png -------------------------------------------------------------------------------- /img/typefoo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/typefoo.png -------------------------------------------------------------------------------- /img/washmachine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/washmachine.png -------------------------------------------------------------------------------- /img/whale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/whale.png -------------------------------------------------------------------------------- /img/wolf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/wolf.png -------------------------------------------------------------------------------- /img/yesno.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/yesno.png -------------------------------------------------------------------------------- /img/yeti.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pvorb/learn-you-a-haskell/e991ba93a51a9f181256e359ce2f0eef89daa7f4/img/yeti.png -------------------------------------------------------------------------------- /metadata.xml: -------------------------------------------------------------------------------- 1 | Attribution-NonCommercial-ShareAlike 3.0 Unported 2 | en-US 3 | -------------------------------------------------------------------------------- /title.txt: -------------------------------------------------------------------------------- 1 | % Learn You a Haskell for Great Good! 2 | % Miran Lipovača 3 | --------------------------------------------------------------------------------