You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/functors-applicative-functors-and-monoids.html
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -233,7 +233,7 @@ <h1>Functors, Applicative Functors and Monoids</h1>
233
233
fmap (\x y z -> x + y / z) [3,4,5,6] :: (Fractional a) => [a -> a -> a]
234
234
</pre>
235
235
<p>If we map <spanclass="fixed">compare</span>, which has a type of <spanclass="fixed">(Ord a) => a -> a -> Ordering</span> over a list of characters, we get a list of functions of type <spanclass="fixed">Char -> Ordering</span>, because the function <spanclass="fixed">compare</span> gets partially applied with the characters in the list. It’s not a list of <spanclass="fixed">(Ord a) => a -> Ordering</span> function, because the first <spanclass="fixed">a</span> that got applied was a <spanclass="fixed">Char</span> and so the second <spanclass="fixed">a</span> has to decide to be of type <spanclass="fixed">Char</span>.</p>
236
-
<p>We see how by mapping "multi-parameter" functions over functors, we get functors that contain functions inside them. So now what can we do with them? Well for one, we can map functions that take these functions as parameters over them, because whatever is inside a functor will be given to the function that we’re mapping over it as a parameter.</p>
236
+
<p>We see how by mapping “multi-parameter” functions over functors, we get functors that contain functions inside them. So now what can we do with them? Well for one, we can map functions that take these functions as parameters over them, because whatever is inside a functor will be given to the function that we’re mapping over it as a parameter.</p>
Copy file name to clipboardExpand all lines: docs/input-and-output.html
+3-3Lines changed: 3 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -353,7 +353,7 @@ <h1>Input and Output</h1>
353
353
<p>Don’t think of a function like <spanclass="fixed">putStrLn</span> as a function that takes a string and prints it to the screen. Think of it as a function that takes a string and returns an I/O action. That I/O action will, when performed, print beautiful poetry to your terminal.</p>
354
354
<aname="files-and-streams"></a><h2>Files and streams</h2>
<p><spanclass="fixed">getChar</span> is an I/O action that reads a single character from the terminal. <spanclass="fixed">getLine</span> is an I/O action that reads a line from the terminal. These two are pretty straightforward and most programming languages have some functions or statements that are parallel to them. But now, let’s meet <spanclass="label function">getContents</span>. <spanclass="fixed">getContents</span> is an I/O action that reads everything from the standard input until it encounters an end-of-file character. Its type is <spanclass="fixed">getContents :: IO String</span>. What’s cool about <spanclass="fixed">getContents</span> is that it does lazy I/O. When we do <spanclass="fixed">foo <- getContents</span>, it doesn’t read all of the input at once, store it in memory and then bind it to <spanclass="fixed">foo</span>. No, it’s lazy! It’ll say: <i>"Yeah yeah, I’ll read the input from the terminal later as we go along, when you really need it!"</i>. </p>
356
+
<p><spanclass="fixed">getChar</span> is an I/O action that reads a single character from the terminal. <spanclass="fixed">getLine</span> is an I/O action that reads a line from the terminal. These two are pretty straightforward and most programming languages have some functions or statements that are parallel to them. But now, let’s meet <spanclass="label function">getContents</span>. <spanclass="fixed">getContents</span> is an I/O action that reads everything from the standard input until it encounters an end-of-file character. Its type is <spanclass="fixed">getContents :: IO String</span>. What’s cool about <spanclass="fixed">getContents</span> is that it does lazy I/O. When we do <spanclass="fixed">foo <- getContents</span>, it doesn’t read all of the input at once, store it in memory and then bind it to <spanclass="fixed">foo</span>. No, it’s lazy! It’ll say: <i>“Yeah yeah, I’ll read the input from the terminal later as we go along, when you really need it!”</i>. </p>
357
357
<p><spanclass="fixed">getContents</span> is really useful when we’re piping the output from one program into the input of our program. In case you don’t know how piping works in unix-y systems, here’s a quick primer. Let’s make a text file that contains the following little haiku:</p>
358
358
<prename="code" class="plain">
359
359
I'm a lil' teapot
@@ -386,7 +386,7 @@ <h1>Input and Output</h1>
386
386
IT'S SO SMALL, TASTELESS
387
387
capslocker <stdin>: hGetLine: end of file
388
388
</pre>
389
-
<p>As you can see, piping the output of one program (in our case that was <i>cat</i>) to the input of another (<i>capslocker</i>) is done with the <spanclass="fixed">|</span> character. What we’ve done is pretty much equivalent to just running <i>capslocker</i>, typing our haiku at the terminal and then issuing an end-of-file character (that’s usually done by pressing Ctrl-D). It’s like running <i>cat haiku.txt</i> and saying: “Wait, don’t print this out to the terminal, tell it to <i>capslocker</i> instead!”.</p>
389
+
<p>As you can see, piping the output of one program (in our case that was <i>cat</i>) to the input of another (<i>capslocker</i>) is done with the <spanclass="fixed">|</span> character. What we’ve done is pretty much equivalent to just running <i>capslocker</i>, typing our haiku at the terminal and then issuing an end-of-file character (that’s usually done by pressing Ctrl-D). It’s like running <i>cat haiku.txt</i> and saying: “Wait, don’t print this out to the terminal, tell it to <i>capslocker</i> instead!”.</p>
390
390
<p>So what we’re essentially doing with that use of <spanclass="fixed">forever</span> is taking the input and transforming it into some output. That’s why we can use <spanclass="fixed">getContents</span> to make our program even shorter and better:</p>
391
391
<prename="code" class="haskell:hs">
392
392
import Data.Char
@@ -410,7 +410,7 @@ <h1>Input and Output</h1>
410
410
lets go
411
411
LETS GO
412
412
</pre>
413
-
<p>We got out of that by pressing Ctrl-D. Pretty nice! As you can see, it prints out our capslocked input back to us line by line. When the result of <spanclass="fixed">getContents</span> is bound to <spanclass="fixed">contents</span>, it’s not represented in memory as a real string, but more like a promise that it will produce the string eventually. When we map <spanclass="fixed">toUpper</span> over <spanclass="fixed">contents</span>, that’s also a promise to map that function over the eventual contents. And finally when <spanclass="fixed">putStr</span> happens, it says to the previous promise: <i>"Hey, I need a capslocked line!"</i>. It doesn’t have any lines yet, so it says to <spanclass="fixed">contents</span>: <i>"Hey, how about actually getting a line from the terminal?"</i>. So that’s when <spanclass="fixed">getContents</span> actually reads from the terminal and gives a line to the code that asked it to produce something tangible. That code then maps <spanclass="fixed">toUpper</span> over that line and gives it to <spanclass="fixed">putStr</span>, which prints it. And then, <spanclass="fixed">putStr</span> says: <i>"Hey, I need the next line, come on!"</i> and this repeats until there’s no more input, which is signified by an end-of-file character.</p>
413
+
<p>We got out of that by pressing Ctrl-D. Pretty nice! As you can see, it prints out our capslocked input back to us line by line. When the result of <spanclass="fixed">getContents</span> is bound to <spanclass="fixed">contents</span>, it’s not represented in memory as a real string, but more like a promise that it will produce the string eventually. When we map <spanclass="fixed">toUpper</span> over <spanclass="fixed">contents</span>, that’s also a promise to map that function over the eventual contents. And finally when <spanclass="fixed">putStr</span> happens, it says to the previous promise: <i>“Hey, I need a capslocked line!”</i>. It doesn’t have any lines yet, so it says to <spanclass="fixed">contents</span>: <i>“Hey, how about actually getting a line from the terminal?”</i>. So that’s when <spanclass="fixed">getContents</span> actually reads from the terminal and gives a line to the code that asked it to produce something tangible. That code then maps <spanclass="fixed">toUpper</span> over that line and gives it to <spanclass="fixed">putStr</span>, which prints it. And then, <spanclass="fixed">putStr</span> says: <i>“Hey, I need the next line, come on!”</i> and this repeats until there’s no more input, which is signified by an end-of-file character.</p>
414
414
<p>Let’s make program that takes some input and prints out only those lines that are shorter than 10 characters. Observe:</p>
Copy file name to clipboardExpand all lines: docs/introduction.html
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -47,7 +47,7 @@ <h2>About this tutorial</h2>
47
47
The channel #haskell on the Libera.Chat network is a great place to ask questions if you’re feeling stuck. People there are extremely nice, patient and understanding to newbies.
48
48
</p>
49
49
<p>
50
-
I failed to learn Haskell approximately 2 times before finally grasping it because it all just seemed too weird to me and I didn’t get it. But then once it just "clicked" and after getting over that initial hurdle, it was pretty much smooth sailing. I guess what I’m trying to say is: Haskell is great and if you’re interested in programming you should really learn it even if it seems weird at first. Learning Haskell is much like learning to program for the first time — it’s fun! It forces you to think differently, which brings us to the next section …
50
+
I failed to learn Haskell approximately 2 times before finally grasping it because it all just seemed too weird to me and I didn’t get it. But then once it just “clicked” and after getting over that initial hurdle, it was pretty much smooth sailing. I guess what I’m trying to say is: Haskell is great and if you’re interested in programming you should really learn it even if it seems weird at first. Learning Haskell is much like learning to program for the first time — it’s fun! It forces you to think differently, which brings us to the next section …
Haskell is <em>lazy</em>. That means that unless specifically told otherwise, Haskell won’t execute functions and calculate things until it’s really forced to show you a result. That goes well with referential transparency and it allows you to think of programs as a series of <em>transformations on data</em>. It also allows cool things such as infinite data structures. Say you have an immutable list of numbers <spanclass="fixed">xs = [1,2,3,4,5,6,7,8]</span> and a function <spanclass="fixed">doubleMe</span> which multiplies every element by 2 and then returns a new list. If we wanted to multiply our list by 8 in an imperative language and did <spanclass="fixed">doubleMe(doubleMe(doubleMe(xs)))</span>, it would probably pass through the list once and make a copy and then return it. Then it would pass through the list another two times and return the result. In a lazy language, calling <spanclass="fixed">doubleMe</span> on a list without forcing it to show you the result ends up in the program sort of telling you "Yeah yeah, I’ll do it later!". But once you want to see the result, the first <spanclass="fixed">doubleMe</span> tells the second one it wants the result, now! The second one says that to the third one and the third one reluctantly gives back a doubled 1, which is a 2. The second one receives that and gives back 4 to the first one. The first one sees that and tells you the first element is 8. So it only does one pass through the list and only when you really need it. That way when you want something from a lazy language you can just take some initial data and efficiently transform and mend it so it resembles what you want at the end.
61
+
Haskell is <em>lazy</em>. That means that unless specifically told otherwise, Haskell won’t execute functions and calculate things until it’s really forced to show you a result. That goes well with referential transparency and it allows you to think of programs as a series of <em>transformations on data</em>. It also allows cool things such as infinite data structures. Say you have an immutable list of numbers <spanclass="fixed">xs = [1,2,3,4,5,6,7,8]</span> and a function <spanclass="fixed">doubleMe</span> which multiplies every element by 2 and then returns a new list. If we wanted to multiply our list by 8 in an imperative language and did <spanclass="fixed">doubleMe(doubleMe(doubleMe(xs)))</span>, it would probably pass through the list once and make a copy and then return it. Then it would pass through the list another two times and return the result. In a lazy language, calling <spanclass="fixed">doubleMe</span> on a list without forcing it to show you the result ends up in the program sort of telling you “Yeah yeah, I’ll do it later!”. But once you want to see the result, the first <spanclass="fixed">doubleMe</span> tells the second one it wants the result, now! The second one says that to the third one and the third one reluctantly gives back a doubled 1, which is a 2. The second one receives that and gives back 4 to the first one. The first one sees that and tells you the first element is 8. So it only does one pass through the list and only when you really need it. That way when you want something from a lazy language you can just take some initial data and efficiently transform and mend it so it resembles what you want at the end.
<p>We’ve already mentioned <spanclass="label function">nub</span>. It takes a list and weeds out the duplicate elements, returning a list whose every element is a unique snowflake! The function does have a kind of strange name. It turns out that "nub" means a small lump or essential part of something. In my opinion, they should use real words for function names instead of old-people words.</p>
331
+
<p>We’ve already mentioned <spanclass="label function">nub</span>. It takes a list and weeds out the duplicate elements, returning a list whose every element is a unique snowflake! The function does have a kind of strange name. It turns out that “nub” means a small lump or essential part of something. In my opinion, they should use real words for function names instead of old-people words.</p>
What if we want a list of all numbers between 1 and 20? Sure, we could just type them all out but obviously that’s not a solution for gentlemen who demand excellence from their programming languages. Instead, we’ll use ranges. Ranges are a way of making lists that are arithmetic sequences of elements that can be enumerated. Numbers can be enumerated. One, two, three, four, etc. Characters can also be enumerated. The alphabet is an enumeration of characters from A to Z. Names can’t be enumerated. What comes after "John"? I don’t know.
368
+
What if we want a list of all numbers between 1 and 20? Sure, we could just type them all out but obviously that’s not a solution for gentlemen who demand excellence from their programming languages. Instead, we’ll use ranges. Ranges are a way of making lists that are arithmetic sequences of elements that can be enumerated. Numbers can be enumerated. One, two, three, four, etc. Characters can also be enumerated. The alphabet is an enumeration of characters from A to Z. Names can’t be enumerated. What comes after “John”? I don’t know.
369
369
</p>
370
370
<p>To make a list containing all the natural numbers from 1 to 20, you just write <spanclass="fixed">[1..20]</span>. That is the equivalent of writing <spanclass="fixed">[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]</span> and there’s no difference between writing one or the other except that writing out long enumeration sequences manually is stupid.</p>
0 commit comments