-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathLessons-Lesson05.html
More file actions
77 lines (77 loc) · 26.5 KB
/
Lessons-Lesson05.html
File metadata and controls
77 lines (77 loc) · 26.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>Lessons.Lesson05</title><link href="linuwial.css" rel="stylesheet" type="text/css" title="Linuwial" /><link rel="stylesheet" type="text/css" href="quick-jump.css" /><link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=PT+Sans:400,400i,700" /><script src="haddock-bundle.min.js" async="async" type="text/javascript"></script><script type="text/x-mathjax-config">MathJax.Hub.Config({ tex2jax: { processClass: "mathjax", ignoreClass: ".*" } });</script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script></head><body><div id="package-header"><span class="caption empty"> </span><ul class="links" id="page-menu"><li><a href="src/Lessons.Lesson05.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>Safe-Inferred</td></tr></table><p class="caption">Lessons.Lesson05</p></div><div id="description"><p class="caption">Description</p><div class="doc"><p>Notes taken by Andrius Gasiukevičius</p></div></div><div id="synopsis"><details id="syn"><summary>Synopsis</summary><ul class="details-toggle" data-details-id="syn"><li class="src short"><span class="keyword">newtype</span> <a href="#t:MySum">MySum</a> = <a href="#v:MySum">MySum</a> {<ul class="subs"><li><a href="#v:getSum">getSum</a> :: Integer</li></ul>}</li><li class="src short"><span class="keyword">type</span> <a href="#t:ErrorMsg">ErrorMsg</a> = [String]</li><li class="src short"><span class="keyword">type</span> <a href="#t:Parser">Parser</a> e a = String -> Either e (a, String)</li><li class="src short"><a href="#v:parseLetter">parseLetter</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> Char</li><li class="src short"><a href="#v:parseString">parseString</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> String</li><li class="src short"><a href="#v:many">many</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e [a]</li><li class="src short"><a href="#v:many1">many1</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> [a]</li><li class="src short"><a href="#v:pmap">pmap</a> :: (a -> b) -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e b</li><li class="src short"><span class="keyword">data</span> <a href="#t:Food">Food</a><ul class="subs"><li>= <a href="#v:Pizza">Pizza</a></li><li>| <a href="#v:Sushi">Sushi</a></li><li>| <a href="#v:Custom">Custom</a> String</li></ul></li><li class="src short"><a href="#v:orElse">orElse</a> :: Semigroup e => <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a</li><li class="src short"><a href="#v:and3">and3</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e b -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e c -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e (a, b, c)</li><li class="src short"><a href="#v:keyword">keyword</a> :: String -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> String</li><li class="src short"><a href="#v:ws">ws</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> [String]</li><li class="src short"><a href="#v:parsePizza">parsePizza</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> <a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a></li><li class="src short"><a href="#v:parseSushi">parseSushi</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> <a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a></li><li class="src short"><a href="#v:parseCustom">parseCustom</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> <a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a></li><li class="src short"><a href="#v:parseFood">parseFood</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> <a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a></li></ul></details></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">newtype</span> <a id="t:MySum" class="def">MySum</a> <a href="src/Lessons.Lesson05.html#MySum" class="link">Source</a> <a href="#t:MySum" class="selflink">#</a></p><div class="doc"><p>Recall that a monoid is a set equipped with a binary operation satisfying the closure, associativity, and identity element properties.
If you're familiar with Groups, you can think of it as a group which does not necessarily have the inverse element property.
Lists are an example of monoids.</p><p>The <code>mappend</code> function represents the binary operation of a monoid ("monoid" + "append" -> "mappend").
Note that many instances of Monoid don't actually <code>append</code> things in the usual sense,
so it's better to generally think of <code>mappend</code> as an abstract binary operation.
For two lists, <code>mappend</code> represents concatenating them into one list (similarly to the ++ operator).</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>mappend [1,2,3] [4,5,6]
</code></strong>[1,2,3,4,5,6]
</pre><p><code>mempty</code> returns the identity value of a given monoid ("monoid" + "empty" -> "mempty").
<code>mempty</code> does not take in any parameters as input, making it a polymorphic constant (determined by its output type) rather than a "proper" function.
The identity value of type '[Integer]' (list containing integers) is an empty list since `l ++ [] == l == [] ++ l` for any list l.</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>mempty :: [Integer]
</code></strong>[]
</pre><p><code>map</code> takes in a function and a list as input, applies the function to every element in the list and returns the function outputs as a new list.
<code>Sum</code> is defined like this (in Data.Monoid):
`newtype Sum a = Sum { getSum :: a }`
which is basically a wrapper with one type parameter <code>a</code> (It also has some derived instances like Eq, Ord, Show, and Read).
So here, we basically convert a list of integers into a list of integer monoids equipped with the addition operation.</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>map Sum [1,2,3]
</code></strong>[Sum {getSum = 1},Sum {getSum = 2},Sum {getSum = 3}]
</pre><p>Recall that 'getSum $ fold $ map Sum [1,2,3]' is equivalent to 'getSum (fold (map Sum [1,2,3]))'.
We already know what 'map Sum [1,2,3]' does from the above explanation.
<code>fold</code> can be used on structures containing monoids to fold them using the monoid's associated binary operation,
with the identity element of the monoid as the initial value of the accumulator.
After folding the list, we get a new monoid 'Sum {getSum = 6}' and unwrap it to extract the value of <code><a href="Lessons-Lesson05.html#t:MySum" title="Lessons.Lesson05">MySum</a></code>.</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>getSum $ fold $ map Sum [1,2,3]
</code></strong>6
</pre><p><code>Product</code> is defined in a very similar way to <code>Sum</code>; it should be pretty easy to understand what the following code does
using similar reasoning as in the previous example.</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>getProduct $ fold $ map Product [1,2,3]
</code></strong>6
</pre><p>Here we define a custom newtype which is similar to Sum, but is restricted to the integers.</p></div><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src"><a id="v:MySum" class="def">MySum</a></td><td class="doc empty"> </td></tr><tr><td colspan="2"><div class="subs fields"><p class="caption">Fields</p><ul><li><dfn class="src"><a id="v:getSum" class="def">getSum</a> :: Integer</dfn><div class="doc empty"> </div></li></ul></div></td></tr></table></div></div><div class="top"><p class="src"><span class="keyword">type</span> <a id="t:ErrorMsg" class="def">ErrorMsg</a> = [String] <a href="src/Lessons.Lesson05.html#ErrorMsg" class="link">Source</a> <a href="#t:ErrorMsg" class="selflink">#</a></p><div class="doc"><p>Any and All are also instances of Monoid. We can define their newtype using a wrapper, similarly to how Sum and Product were defined.
Any is equipped with the binary operation || (logical OR) and has <code>False</code> as its identity value since 'False || True == True' and 'False || False == False'.
All is equipped with the binary operation && (logical AND) and has <code>True</code> as its identity value since 'True && True == True' and 'True && False == False'.
Below are some examples of folding lists containing Any and All monoids.</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>fold $ map All [True, True]
</code></strong>All {getAll = True}
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>fold $ map All [True, True, False]
</code></strong>All {getAll = False}
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>fold $ map Any [True, True, False]
</code></strong>Any {getAny = True}
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>fold $ map Any [False, False]
</code></strong>Any {getAny = False}
</pre><p>We define a parser similarly to the way it was done in Lesson 4.
This time, the parser can return a value of type <code>e</code> instead of just ErrorMsg as its Left value.
Also, ErrorMsg is a list of <code>String</code>s instead of a single String.</p></div></div><div class="top"><p class="src"><span class="keyword">type</span> <a id="t:Parser" class="def">Parser</a> e a = String -> Either e (a, String) <a href="src/Lessons.Lesson05.html#Parser" class="link">Source</a> <a href="#t:Parser" class="selflink">#</a></p></div><div class="top"><p class="src"><a id="v:parseLetter" class="def">parseLetter</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> Char <a href="src/Lessons.Lesson05.html#parseLetter" class="link">Source</a> <a href="#v:parseLetter" class="selflink">#</a></p><div class="doc"><p>This parser attempts to parse a single letter from the beginning of the string.
It works similarly to <code><a href="Lessons-Lesson05.html#v:parseLetter" title="Lessons.Lesson05">parseLetter</a></code> from Lesson 4 (essentially rewriting it to support the new Parser and ErrorMsg definitions).</p></div></div><div class="top"><p class="src"><a id="v:parseString" class="def">parseString</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> String <a href="src/Lessons.Lesson05.html#parseString" class="link">Source</a> <a href="#v:parseString" class="selflink">#</a></p><div class="doc"><p><code><a href="Lessons-Lesson05.html#v:parseString" title="Lessons.Lesson05">parseString</a></code> attempts to parse a string. It repeatedly attempts to read letters from the start of the input and
succeeds if it is able to find at least one letter. The parser stops upon encountering a non-letter character.
(The setup is again similar to the parser from Lesson 4, but with support to the new ErrorMsg and Parser definitions).</p></div></div><div class="top"><p class="src"><a id="v:many" class="def">many</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e [a] <a href="src/Lessons.Lesson05.html#many" class="link">Source</a> <a href="#v:many" class="selflink">#</a></p><div class="doc"><p>The <code><a href="Lessons-Lesson05.html#v:many" title="Lessons.Lesson05">many</a></code> parser runs another parser <code>many'</code> repeatedly on the input
(similarly to <code><a href="Lessons-Lesson05.html#v:many" title="Lessons.Lesson05">many</a></code> from Lesson 4, but this time <code><a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a></code> has an additional type parameter).
Note that <code><a href="Lessons-Lesson05.html#v:many" title="Lessons.Lesson05">many</a></code> p' (acc ++ [v]) r` is equivalent to `(many' p' (acc ++ [v])) r`
since many' returns a function which takes <code>r</code> as input.</p></div></div><div class="top"><p class="src"><a id="v:many1" class="def">many1</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> [a] <a href="src/Lessons.Lesson05.html#many1" class="link">Source</a> <a href="#v:many1" class="selflink">#</a></p><div class="doc"><p>The parser <code><a href="Lessons-Lesson05.html#v:many1" title="Lessons.Lesson05">many1</a></code> requires at least one value to be parsed.
Note that 'many p input' is equivalent to '(many p) input' since 'many p' returns a parser.</p></div></div><div class="top"><p class="src"><a id="v:pmap" class="def">pmap</a> :: (a -> b) -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e b <a href="src/Lessons.Lesson05.html#pmap" class="link">Source</a> <a href="#v:pmap" class="selflink">#</a></p><div class="doc"><p><code><a href="Lessons-Lesson05.html#v:pmap" title="Lessons.Lesson05">pmap</a></code> maps a parser which parses values of type <code>a</code> to a parser which parses values of type <code>b</code> using a given function <code>f</code>.
The function does not map Left values (error messages); only the parsed values of Right are affected.
If the parser p parses a Right value 'Right (v, r)', it gets mapped to 'Right (f v, r)'.</p></div></div><div class="top"><p class="src"><span class="keyword">data</span> <a id="t:Food" class="def">Food</a> <a href="src/Lessons.Lesson05.html#Food" class="link">Source</a> <a href="#t:Food" class="selflink">#</a></p><div class="doc"><p>Here we define an algebraic data type <code><a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a></code>. Clearly, the most important foods are Pizza and Sushi; the rest can be described by a Custom String.</p></div><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src"><a id="v:Pizza" class="def">Pizza</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a id="v:Sushi" class="def">Sushi</a></td><td class="doc empty"> </td></tr><tr><td class="src"><a id="v:Custom" class="def">Custom</a> String</td><td class="doc empty"> </td></tr></table></div><div class="subs instances"><h4 class="instances details-toggle-control details-toggle" data-details-id="i:Food">Instances</h4><details id="i:Food" open="open"><summary class="hide-when-js-enabled">Instances details</summary><table><tr><td class="src clearfix"><span class="inst-left"><span class="instance details-toggle-control details-toggle" data-details-id="i:id:Food:Show:1"></span> Show <a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a></span> <a href="src/Lessons.Lesson05.html#line-135" class="link">Source</a> <a href="#t:Food" class="selflink">#</a></td><td class="doc empty"> </td></tr><tr><td colspan="2"><details id="i:id:Food:Show:1"><summary class="hide-when-js-enabled">Instance details</summary><p>Defined in <a href="Lessons-Lesson05.html">Lessons.Lesson05</a></p> <div class="subs methods"><p class="caption">Methods</p><p class="src"><a href="#v:showsPrec">showsPrec</a> :: Int -> <a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a> -> ShowS</p><p class="src"><a href="#v:show">show</a> :: <a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a> -> String</p><p class="src"><a href="#v:showList">showList</a> :: [<a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a>] -> ShowS</p></div></details></td></tr></table></details></div></div><div class="top"><p class="src"><a id="v:orElse" class="def">orElse</a> :: Semigroup e => <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a <a href="src/Lessons.Lesson05.html#orElse" class="link">Source</a> <a href="#v:orElse" class="selflink">#</a></p><div class="doc"><p>A semigroup is a set equipped with a binary operation satisfying the closure and associativity properties.
You can think of it as a Monoid that does not necessarily have an identity element.
| orElse is a function combining two parsers into one.
Given two parsers <code>p1</code> and <code>p2</code>:
<code><a href="Lessons-Lesson05.html#v:orElse" title="Lessons.Lesson05">orElse</a></code> returns 'Right r1', if <code>p1</code> parses the input given to the combined parser as a <code>Right</code> type with value <code>r1</code>
Otherwise, <code><a href="Lessons-Lesson05.html#v:orElse" title="Lessons.Lesson05">orElse</a></code> returns 'Right r2' if <code>p2</code> parses the input given to the combined parser as a <code>Right</code> type with value <code>r2</code>
Otherwise, <code><a href="Lessons-Lesson05.html#v:orElse" title="Lessons.Lesson05">orElse</a></code> returns 'Left $ e1 <> e2' where <code><></code> is an alias for <code>mappend</code>.
So basically, <code><a href="Lessons-Lesson05.html#v:orElse" title="Lessons.Lesson05">orElse</a></code> takes the output of the first parser which parses the input, or returns an error if no parser can process the input.</p></div></div><div class="top"><p class="src"><a id="v:and3" class="def">and3</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e a -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e b -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e c -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> e (a, b, c) <a href="src/Lessons.Lesson05.html#and3" class="link">Source</a> <a href="#v:and3" class="selflink">#</a></p><div class="doc"><p>and3 is a function combining three parsers into one.
It attempts to parse the input using three parsers in a row, with each parser receiving the remaining unparsed text as input.
If any parser returns an error, the combined parser returns an error as well.
If all three parsers successfully parse the input, a tuple of parsed values '(v1, v2, v3)' is returned as a Right value.</p></div></div><div class="top"><p class="src"><a id="v:keyword" class="def">keyword</a> :: String -> <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> String <a href="src/Lessons.Lesson05.html#keyword" class="link">Source</a> <a href="#v:keyword" class="selflink">#</a></p><div class="doc"><p>Expanding the definition of <code><a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a></code>, we see that keyword :: String -> String -> Either ErrorMsg (String, String)
Hence <code><a href="Lessons-Lesson05.html#v:keyword" title="Lessons.Lesson05">keyword</a></code> can be understood as a function which takes in two strings and returns an Either (by function associativity).
It checks if a given prefix is a prefix of the input being parsed and returns a Right value with the prefix and remaining input if this is the case.
Otherwise, it returns a Left value (a list containing an error message).</p></div></div><div class="top"><p class="src"><a id="v:ws" class="def">ws</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> [String] <a href="src/Lessons.Lesson05.html#ws" class="link">Source</a> <a href="#v:ws" class="selflink">#</a></p><div class="doc"><p><code><a href="Lessons-Lesson05.html#v:ws" title="Lessons.Lesson05">ws</a></code> parses whitespace (tab or space) characters (at least one) using <code><a href="Lessons-Lesson05.html#v:keyword" title="Lessons.Lesson05">keyword</a></code> and <code><a href="Lessons-Lesson05.html#v:orElse" title="Lessons.Lesson05">orElse</a></code>.</p></div></div><div class="top"><p class="src"><a id="v:parsePizza" class="def">parsePizza</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> <a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a> <a href="src/Lessons.Lesson05.html#parsePizza" class="link">Source</a> <a href="#v:parsePizza" class="selflink">#</a></p><div class="doc"><p>'const x y' always evaluates to <code>x</code>.
| <code><a href="Lessons-Lesson05.html#v:parsePizza" title="Lessons.Lesson05">parsePizza</a></code> returns a parser which returns a Right value whenever the input text starts with "pizza".
Due to the parser map applied on the 'keyword "pizza"' function, the value of Right gets replaced by
the actual Pizza (of type Food) (so "pizza" becomes Pizza).</p></div></div><div class="top"><p class="src"><a id="v:parseSushi" class="def">parseSushi</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> <a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a> <a href="src/Lessons.Lesson05.html#parseSushi" class="link">Source</a> <a href="#v:parseSushi" class="selflink">#</a></p><div class="doc"><p>parseSushi works very similarly to <code><a href="Lessons-Lesson05.html#v:parsePizza" title="Lessons.Lesson05">parsePizza</a></code>, but for sushi instead.</p></div></div><div class="top"><p class="src"><a id="v:parseCustom" class="def">parseCustom</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> <a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a> <a href="src/Lessons.Lesson05.html#parseCustom" class="link">Source</a> <a href="#v:parseCustom" class="selflink">#</a></p><div class="doc"><p>parseCustom parses a string of the form "custom <a href="whitespace">whitespace</a> <a href="string">string</a>" using a combined <code><a href="Lessons-Lesson05.html#v:and3" title="Lessons.Lesson05">and3</a></code> parser.
This output of this parser gets mapped to a Custom food output using <code><a href="Lessons-Lesson05.html#v:pmap" title="Lessons.Lesson05">pmap</a></code>.</p></div></div><div class="top"><p class="src"><a id="v:parseFood" class="def">parseFood</a> :: <a href="Lessons-Lesson05.html#t:Parser" title="Lessons.Lesson05">Parser</a> <a href="Lessons-Lesson05.html#t:ErrorMsg" title="Lessons.Lesson05">ErrorMsg</a> <a href="Lessons-Lesson05.html#t:Food" title="Lessons.Lesson05">Food</a> <a href="src/Lessons.Lesson05.html#parseFood" class="link">Source</a> <a href="#v:parseFood" class="selflink">#</a></p><div class="doc"><p>parseFood parses a food item using the <code><a href="Lessons-Lesson05.html#v:orElse" title="Lessons.Lesson05">orElse</a></code> function to combine multiple parsers into one.
Some examples:</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>parseFood "pizza fdsf"
</code></strong>Right (Pizza," fdsf")
<code class="prompt">>>> </code><strong class="userinput"><code>parseFood "sushi"
</code></strong>Right (Sushi,"")
<code class="prompt">>>> </code><strong class="userinput"><code>parseFood "custom buritto "
</code></strong>Right (Custom "buritto"," ")
<code class="prompt">>>> </code><strong class="userinput"><code>parseFood "customburitto "
</code></strong>Left ["pizza is expected, got customburitto ","sushi is expected, got customburitto ","At least on value required"]
<code class="prompt">>>> </code><strong class="userinput"><code>parseFood "custom "
</code></strong>Left ["pizza is expected, got custom ","sushi is expected, got custom ","At least on value required"]
</pre></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.29.2</p></div></body></html>