An advanced, purely functional programming language
Lists and Tuples
You can only have a list of numbers or a list of characters, whereas in a tuple you can throw anything in!
We've also seen that you can make a new list with (:) that joins two values together, like:
λ 1 : [2,3]
[1,2,3]:: Num a => [a]
But we can't do this with tuples! You can only write a tuple and then look at what's inside. You can't make new ones on the fly like a list.
Let's write our own functions! It's really easy. How about something simple:
let square x = x * x in square 3
Let there be functions
Nice one! I think you're getting used to the let syntax.
You defined a function. You can read it as, as for a given parameter called x, square of x is x * x.
Some others you can try are:
let add1 x = x + 1 in add1 5
let second x = snd x in second (3,4)
Let's go crazy and use our square function with map:
let square x = x * x in map square [1..10]
λ let add1 x = x + 1 in add1 5
6:: Num a => a
λ let second x = snd x in second (3,4)
4:: Num b => b
λ let square x = x * x in map square [1..10]
[1,4,9,16,25,36,49,64,81,100]:: (Enum b, Num b) => [b]
Let there be functions
That's so cool! You described a simple function square and then you just passed it to another function (map) and got back [1,4,9,16,25,36,49,64,81,100], exactly what you expected!
Haskell is pretty good at composing things together like this. Some other things you can try are:
let add1 x = x + 1 in map add1 [1,5,7]
let take5s = filter (==5) in take5s [1,5,2,5,3,5]
let take5s = filter (==5) in map take5s [[1,5],[5],[1,1]]
Did you get back what you expected?
One more example for text; how do you upcase a letter?
toUpper 'a'
λ let add1 x = x + 1 in map add1 [1,5,7]
[2,6,8]:: Num b => [b]
λ let take5s = filter (==5) in take5s [1,5,2,5,3,5]
[5,5,5]:: (Eq a, Num a) => [a]
λ let take5s = filter (==5) in map take5s [[1,5],[5],[1,1]]
[[5],[5],[]]:: (Eq a, Num a) => [[a]]
Exercise time!
Easy! Remember: characters are written like 'a' and strings (lists of characters) are written like "a".
I need you to use toUpper capitalise my whole name, "Chris". Give it a try. You can do it, I believe in you!
Lesson 4 complete!
Brilliant! You're making excellent progress! You just passed toUpper to map. No problem.
Let's go over what you've learned in this lesson:
Functions like map take other functions as parameters.
Functions like (+1), (>5) and square can be passed to other functions.
Defining functions is just a case of writing what to do with the parameters.
Let's check out pattern matching; a way to get values from other values using patterns. Try this:
let (a,b) = (10,12) in a * 2
Ignorance is bliss
You're getting into tricky syntax, huh? I know you can handle it!
If you just want some of the values, you can ignore the others with _ (underscore) like this:
let (a:::_) = "xyz" in a
In fact, (a:b:c:d) is short-hand for (a:(b:(c:d))), so you can just ignore the rest in one go:
let (a:_) = "xyz" in a
λ let (a,b) = (10,12) in a * 2
20:: Num a => a
λ let (a:_:_:_) = "xyz" in a
'x':: Char
λ let (a:_) = "xyz" in a
'x':: Char
Show me the money!
Try to get the 'a' value from this value using pattern matching:
(10,"abc")
Perfetto!
Wizard! I think you've got pattern-matching down.
If you're still a bit unsure, here are some other things you can try:
let ::c:_ = "abcd" in c
let [a,b,c] = "cat" in (a,b,c)
You can also grab a whole value and pattern match on it (have your cake and eat it too):
let abc@(a,b,c) = (10,20,30) in (abc,a,b,c)
And that's the end of that chapter
That was easy, right?
Let's go over what you've learned in this lesson:
- Values are pattern matched, or deconstructed, by writing however they were constructed.
- Patterns let you use the values that you match.
- You can ignore whichever values you want.
- You can pattern match and keep hold of the original value too.
Okay! That's all for now. It's time to dig into some documentation!