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/introduction.html
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -68,7 +68,7 @@ <h2>About this tutorial</h2>
68
68
Haskell is <em>elegant and concise</em>. Because it uses a lot of high level concepts, Haskell programs are usually shorter than their imperative equivalents. And shorter programs are easier to maintain than longer ones and have less bugs.
69
69
</p>
70
70
<p>
71
-
Haskell was made by some <em>really smart guys</em> (with PhDs). Work on Haskell began in 1987 when a committee of researchers got together to design a kick-ass language. In 2003 the Haskell Report was published, which defines a stable version of the language.
71
+
Haskell was made by some <em>really smart folk</em> (with PhDs). Work on Haskell began in 1987 when a committee of researchers got together to design a kick-ass language. In 2003 the Haskell Report was published, which defines a stable version of the language.
72
72
</p>
73
73
<aname="what-you-need"></a><h2>What you need to dive in</h2>
Copy file name to clipboardExpand all lines: docs/making-our-own-types-and-typeclasses.html
+7-7Lines changed: 7 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -488,12 +488,12 @@ <h1>Making Our Own Types and Typeclasses</h1>
488
488
<prename="code" class="haskell:hs">
489
489
phoneBook :: [(String,String)]
490
490
phoneBook =
491
-
[("betty","555-2938")
492
-
,("bonnie","452-2928")
493
-
,("patsy","493-2928")
494
-
,("lucille","205-2928")
495
-
,("wendy","939-8282")
496
-
,("penny","853-2492")
491
+
[("amelia","555-2938")
492
+
,("freya","452-2928")
493
+
,("isabella","493-2928")
494
+
,("neil","205-2928")
495
+
,("roald","939-8282")
496
+
,("tenzing","853-2492")
497
497
]</pre>
498
498
<p>We see that the type of <spanclass="fixed">phoneBook</span> is <spanclass="fixed">[(String,String)]</span>. That tells us that it's an association list that maps from strings to strings, but not much else. Let's make a type synonym to convey some more information in the type declaration.</p>
499
499
<prename="code" class="haskell:hs">
@@ -517,7 +517,7 @@ <h1>Making Our Own Types and Typeclasses</h1>
517
517
type AssocList k v = [(k,v)]
518
518
</pre>
519
519
<p>Now, a function that gets the value by a key in an association list can have a type of <spanclass="fixed">(Eq k) => k -> AssocList k v -> Maybe v</span>. <spanclass="fixed">AssocList</span> is a type constructor that takes two types and produces a concrete type, like <spanclass="fixed">AssocList Int String</span>, for instance.</p>
520
-
<divclass="hintbox"><em>Fonzie says:</em> Aaay! When I talk about <i>concrete types</i> I mean like fully applied types like <spanclass="fixed">Map Int String</span> or if we're dealin' with one of them polymorphic functions, <spanclass="fixed">[a]</span> or <spanclass="fixed">(Ord a) => Maybe a</span> and stuff. And like, sometimes me and the boys say that <spanclass="fixed">Maybe</span> is a type, but we don't mean that, cause every idiot knows <spanclass="fixed">Maybe</span> is a type constructor. When I apply an extra type to <spanclass="fixed">Maybe</span>, like <spanclass="fixed">Maybe String</span>, then I have a concrete type. You know, values can only have types that are concrete types! So in conclusion, live fast, love hard and don't let anybody else use your comb!</div>
520
+
<divclass="hintbox"><em>Fonzie says:</em> Aaay! When I talk about <i>concrete types</i> I mean like fully applied types like <spanclass="fixed">Map Int String</span> or if we're dealin' with one of them polymorphic functions, <spanclass="fixed">[a]</span> or <spanclass="fixed">(Ord a) => Maybe a</span> and stuff. And like, sometimes me and my buddies say that <spanclass="fixed">Maybe</span> is a type, but we don't mean that, cause every idiot knows <spanclass="fixed">Maybe</span> is a type constructor. When I apply an extra type to <spanclass="fixed">Maybe</span>, like <spanclass="fixed">Maybe String</span>, then I have a concrete type. You know, values can only have types that are concrete types! So in conclusion, live fast, love hard and don't let anybody else use your comb!</div>
521
521
<p>Just like we can partially apply functions to get new functions, we can partially apply type parameters and get new type constructors from them. Just like we call a function with too few parameters to get back a new function, we can specify a type constructor with too few type parameters and get back a partially applied type constructor. If we wanted a type that represents a map (from <spanclass="fixed">Data.Map</span>) from integers to something, we could either do this:</p>
Copy file name to clipboardExpand all lines: docs/modules.html
+36-36Lines changed: 36 additions & 36 deletions
Original file line number
Diff line number
Diff line change
@@ -83,16 +83,16 @@ <h1>Modules</h1>
83
83
</pre>
84
84
<p><spanclass="label function">intercalate</span> takes a list and a list of lists. It then inserts that list in between all those lists and then flattens the result.</p>
<p><spanclass="label function">transpose</span> transposes a list of lists. If you look at a list of lists as a 2D matrix, the columns become the rows and vice versa.</p>
92
92
<prename="code" class="haskell:ghci">
93
93
ghci> transpose [[1,2,3],[4,5,6],[7,8,9]]
94
94
[[1,4,7],[2,5,8],[3,6,9]]
95
-
ghci> transpose ["hey","there","guys"]
95
+
ghci> transpose ["hey","there","folks"]
96
96
["htg","ehu","yey","rs","e"]
97
97
</pre>
98
98
<p>Say we have the polynomials <i>3x<sup>2</sup> + 5x + 9</i>, <i>10x<sup>3</sup> + 9</i> and <i>8x<sup>3</sup> + 5x<sup>2</sup> + x - 1</i> and we want to add them together. We can use the lists <spanclass="fixed">[0,3,5,9]</span>, <spanclass="fixed">[10,0,0,9]</span> and <spanclass="fixed">[8,5,1,-1]</span> to represent them in Haskell. Now, to add them, all we have to do is this:</p>
@@ -442,16 +442,16 @@ <h1>Modules</h1>
442
442
<p>Kewl. In case you don't remember, <spanclass="fixed">all</span> takes a predicate and a list and returns <spanclass="fixed">True</span> only if that predicate holds for every element in the list.</p>
443
443
<p>We can also use <spanclass="fixed">isSpace</span> to simulate the <spanclass="fixed">Data.List</span> function <spanclass="fixed">words</span>.
444
444
<prename="code" class="haskell:ghci">
445
-
ghci> words "hey guys its me"
446
-
["hey","guys","its","me"]
447
-
ghci> groupBy ((==) `on` isSpace) "hey guys its me"
448
-
["hey"," ","guys"," ","its"," ","me"]
445
+
ghci> words "hey folks its me"
446
+
["hey","folks","its","me"]
447
+
ghci> groupBy ((==) `on` isSpace) "hey folks its me"
448
+
["hey"," ","folks"," ","its"," ","me"]
449
449
ghci>
450
450
</pre>
451
451
<p>Hmmm, well, it kind of does what <spanclass="fixed">words</span> does but we're left with elements of only spaces. Hmm, whatever shall we do? I know, let's filter that sucker.</p>
452
452
<prename="code" class="haskell:ghci">
453
-
ghci> filter (not . any isSpace) . groupBy ((==) `on` isSpace) $ "hey guys its me"
454
-
["hey","guys","its","me"]
453
+
ghci> filter (not . any isSpace) . groupBy ((==) `on` isSpace) $ "hey folks its me"
454
+
["hey","folks","its","me"]
455
455
</pre>
456
456
<p>Ah.</p>
457
457
<p>The <spanclass="fixed">Data.Char</span> also exports a datatype that's kind of like <spanclass="fixed">Ordering</span>. The <spanclass="fixed">Ordering</span> type can have a value of <spanclass="fixed">LT</span>, <spanclass="fixed">EQ</span> or <spanclass="fixed">GT</span>. It's a sort of enumeration. It describes a few possible results that can arise from comparing two elements. The <spanclass="fixed">GeneralCategory</span> type is also an enumeration. It presents us with a few possible categories that a character can fall into. The main function for getting the general category of a character is <spanclass="fixed">generalCategory</span>. It has a type of <spanclass="fixed">generalCategory :: Char -> GeneralCategory</span>. There are about 31 categories so we won't list them all here, but let's play around with the function.</p>
@@ -533,12 +533,12 @@ <h1>Modules</h1>
533
533
<p>The most obvious way to represent association lists in Haskell would be by having a list of pairs. The first component in the pair would be the key, the second component the value. Here's an example of an association list with phone numbers:</p>
534
534
<prename="code" class="haskell:hs">
535
535
phoneBook =
536
-
[("betty","555-2938")
537
-
,("bonnie","452-2928")
538
-
,("patsy","493-2928")
539
-
,("lucille","205-2928")
540
-
,("wendy","939-8282")
541
-
,("penny","853-2492")
536
+
[("amelia","555-2938")
537
+
,("freya","452-2928")
538
+
,("isabella","493-2928")
539
+
,("neil","205-2928")
540
+
,("roald","939-8282")
541
+
,("tenzing","853-2492")
542
542
]
543
543
</pre>
544
544
<p>Despite this seemingly odd indentation, this is just a list of pairs of strings. The most common task when dealing with association lists is looking up some value by key. Let's make a function that looks up some value given a key.</p>
@@ -562,15 +562,15 @@ <h1>Modules</h1>
562
562
</pre>
563
563
<divclass="hintbox"><em>Note:</em> It's usually better to use folds for this standard list recursion pattern instead of explicitly writing the recursion because they're easier to read and identify. Everyone knows it's a fold when they see the <spanclass="fixed">foldr</span> call, but it takes some more thinking to read explicit recursion.</div>
<p>Works like a charm! If we have the girl's phone number, we <spanclass="fixed">Just</span> get the number, otherwise we get <spanclass="fixed">Nothing</span>.</p>
573
+
<p>Works like a charm! If we have the friend's phone number, we <spanclass="fixed">Just</span> get the number, otherwise we get <spanclass="fixed">Nothing</span>.</p>
574
574
<p>We just implemented the <spanclass="fixed">lookup</span> function from <spanclass="fixed">Data.List</span>. If we want to find the corresponding value to a key, we have to traverse all the elements of the list until we find it. The <spanclass="fixed">Data.Map</span> module offers association lists that are much faster (because they're internally implemented with trees) and also it provides a lot of utility functions. From now on, we'll say we're working with maps instead of association lists.</p>
575
575
<p>Because <spanclass="fixed">Data.Map</span> exports functions that clash with the <spanclass="fixed">Prelude</span> and <spanclass="fixed">Data.List</span> ones, we'll do a qualified import.
576
576
<prename="code" class="haskell:hs">
@@ -580,8 +580,8 @@ <h1>Modules</h1>
580
580
<p>Let's go ahead and see what <spanclass="fixed">Data.Map</span> has in store for us! Here's the basic rundown of its functions.</p>
581
581
<p>The <spanclass="label function">fromList</span> function takes an association list (in the form of a list) and returns a map with the same associations.</p>
<p><spanclass="label function">keys</span> and <spanclass="label function">elems</span> return lists of keys and values respectively. <spanclass="fixed">keys</span> is the equivalent of <spanclass="fixed">map fst . Map.toList</span> and <spanclass="fixed">elems</span> is the equivalent of <spanclass="fixed">map snd . Map.toList</span>.</p>
658
-
<p><spanclass="label function">fromListWith</span> is a cool little function. It acts like <spanclass="fixed">fromList</span>, only it doesn't discard duplicate keys but it uses a function supplied to it to decide what to do with them. Let's say that a girl can have several numbers and we have an association list set up like this.</p>
658
+
<p><spanclass="label function">fromListWith</span> is a cool little function. It acts like <spanclass="fixed">fromList</span>, only it doesn't discard duplicate keys but it uses a function supplied to it to decide what to do with them. Let's say that a friend can have several numbers and we have an association list set up like this.</p>
659
659
<prename="code" class="haskell:hs">
660
660
phoneBook =
661
-
[("betty","555-2938")
662
-
,("betty","342-2492")
663
-
,("bonnie","452-2928")
664
-
,("patsy","493-2928")
665
-
,("patsy","943-2929")
666
-
,("patsy","827-9162")
667
-
,("lucille","205-2928")
668
-
,("wendy","939-8282")
669
-
,("penny","853-2492")
670
-
,("penny","555-2111")
661
+
[("amelia","555-2938")
662
+
,("amelia","342-2492")
663
+
,("freya","452-2928")
664
+
,("isabella","493-2928")
665
+
,("isabella","943-2929")
666
+
,("isabella","827-9162")
667
+
,("neil","205-2928")
668
+
,("roald","939-8282")
669
+
,("tenzing","853-2492")
670
+
,("tenzing","555-2111")
671
671
]
672
672
</pre>
673
673
<p>Now if we just use <spanclass="fixed">fromList</span> to put that into a map, we'll lose a few numbers! So here's what we'll do:</p>
<p>If a duplicate key is found, the function we pass is used to combine the values of those keys into some other value. We could also first make all the values in the association list singleton lists and then we can use <spanclass="fixed">++</span> to combine the numbers.</p>
<p>Pretty neat! Another use case is if we're making a map from an association list of numbers and when a duplicate key is found, we want the biggest value for the key to be kept.</p>
0 commit comments