-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathLessons-Lesson04.html
More file actions
58 lines (58 loc) · 15.3 KB
/
Lessons-Lesson04.html
File metadata and controls
58 lines (58 loc) · 15.3 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
<!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.Lesson04</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.Lesson04.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.Lesson04</p></div><div id="description"><p class="caption">Description</p><div class="doc"><p>Notes taken by Ugnė Pacevičiūtė </p></div></div><div id="synopsis"><details id="syn"><summary>Synopsis</summary><ul class="details-toggle" data-details-id="syn"><li class="src short"><a href="#v:add">add</a> :: Int -> Int -> Int</li><li class="src short"><a href="#v:sumOfInts">sumOfInts</a> :: [Int] -> Int</li><li class="src short"><a href="#v:mapping">mapping</a> :: (a -> b) -> [a] -> [b]</li><li class="src short"><a href="#v:safeDivision">safeDivision</a> :: Integer -> Integer -> Either String Integer</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> a = String -> Either <a href="Lessons-Lesson04.html#t:ErrorMsg" title="Lessons.Lesson04">ErrorMsg</a> (a, String)</li><li class="src short"><a href="#v:parseLetter">parseLetter</a> :: <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> Char</li><li class="src short"><a href="#v:parseDigit">parseDigit</a> :: <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> Char</li><li class="src short"><a href="#v:many">many</a> :: <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> a -> <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> [a]</li><li class="src short"><a href="#v:many1">many1</a> :: <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> a -> <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> [a]</li><li class="src short"><a href="#v:parseString">parseString</a> :: <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> String</li><li class="src short"><a href="#v:pmap">pmap</a> :: (a -> b) -> <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> a -> <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> b</li><li class="src short"><a href="#v:parseInteger">parseInteger</a> :: <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> Integer</li></ul></details></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><a id="v:add" class="def">add</a> :: Int -> Int -> Int <a href="src/Lessons.Lesson04.html#add" class="link">Source</a> <a href="#v:add" class="selflink">#</a></p><div class="doc"><p>The <code><a href="Lessons-Lesson04.html#v:add" title="Lessons.Lesson04">add</a></code> function takes two integers and returns their sum.
It is a simple example of a named function definition.</p></div></div><div class="top"><p class="src"><a id="v:sumOfInts" class="def">sumOfInts</a> :: [Int] -> Int <a href="src/Lessons.Lesson04.html#sumOfInts" class="link">Source</a> <a href="#v:sumOfInts" class="selflink">#</a></p><div class="doc"><p>Anonymous functions (and one of their implementations - lambda functions) are functions without a name.
In Haskell, they are written using a backslash `\`, followed by their parameters.</p><p>The function below demonstrates how <code>foldl</code> can be used with both named and anonymous functions.
<code>foldl</code> stands for fold left, meaning it combines all elements of a list using a binary function.</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>foldl add 0 [1,2,3,4,5]
</code></strong>15
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>foldl add 0 []
</code></strong>0
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>foldl add (-1) []
</code></strong>-1
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>foldl (\a b -> a * b) 1 [1,2,3,4]
</code></strong>24
</pre></div></div><div class="top"><p class="src"><a id="v:mapping" class="def">mapping</a> :: (a -> b) -> [a] -> [b] <a href="src/Lessons.Lesson04.html#mapping" class="link">Source</a> <a href="#v:mapping" class="selflink">#</a></p><div class="doc"><p>In this example, <code>t</code> represents the tail of a list — that is, all elements except the first.
This function shows how to apply a given function <code>f</code> to every element in the list.</p><p>It is essentially a reimplementation of Haskell’s built-in <code>map</code> function.</p></div></div><div class="top"><p class="src"><a id="v:safeDivision" class="def">safeDivision</a> :: Integer -> Integer -> Either String Integer <a href="src/Lessons.Lesson04.html#safeDivision" class="link">Source</a> <a href="#v:safeDivision" class="selflink">#</a></p><div class="doc"><p>The <code>Either</code> type is used to represent computations that can return one of two possible results — typically an error (Left) or a success (Right).</p><p>This function safely performs integer division. If the divisor is zero, it returns an error message wrapped in <code>Left</code>. Otherwise, it returns the result in <code>Right</code>.</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>safeDivision 1 0
</code></strong>Left "Division by zero"
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>safeDivision 1 10
</code></strong>Right 0
</pre></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.Lesson04.html#ErrorMsg" class="link">Source</a> <a href="#t:ErrorMsg" class="selflink">#</a></p><div class="doc"><p>The type 'Parser a' represents a function that takes a string and tries to extract a value of type <code>a</code> from its beginning.
It returns either:
<code>Left</code> with an error message, or
<code>Right</code> with a tuple (<code>a</code>, <code>String</code>) — the parsed value and the remaining input.</p></div></div><div class="top"><p class="src"><span class="keyword">type</span> <a id="t:Parser" class="def">Parser</a> a = String -> Either <a href="Lessons-Lesson04.html#t:ErrorMsg" title="Lessons.Lesson04">ErrorMsg</a> (a, String) <a href="src/Lessons.Lesson04.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-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> Char <a href="src/Lessons.Lesson04.html#parseLetter" class="link">Source</a> <a href="#v:parseLetter" class="selflink">#</a></p><div class="doc"><p>This parser tries to read a single alphabetic letter from the beginning of a string.</p><p>If the input is empty, it fails with an error message.
If the first character is a letter, it returns it along with the rest of the string.
Otherwise, it returns an error describing what went wrong.</p><p>The operator <code>$</code> allows us to avoid parentheses for function application.</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>parseLetter "fksdjhfdjk"
</code></strong>Right ('f',"ksdjhfdjk")
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>parseLetter ""
</code></strong>Left "A letter is expected but got empty input"
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>parseLetter "3213fksdjhfdjk"
</code></strong>Left "A letter is expected, but got 3"
</pre></div></div><div class="top"><p class="src"><a id="v:parseDigit" class="def">parseDigit</a> :: <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> Char <a href="src/Lessons.Lesson04.html#parseDigit" class="link">Source</a> <a href="#v:parseDigit" class="selflink">#</a></p><div class="doc"><p>This parser works similarly to <code><a href="Lessons-Lesson04.html#v:parseLetter" title="Lessons.Lesson04">parseLetter</a></code>, but it checks for digits.</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>parseDigit "ghfjkd"
</code></strong>Left "A digit is expected, but got g"
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>parseDigit "55ghfjkd"
</code></strong>Right ('5',"5ghfjkd")
</pre></div></div><div class="top"><p class="src"><a id="v:many" class="def">many</a> :: <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> a -> <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> [a] <a href="src/Lessons.Lesson04.html#many" class="link">Source</a> <a href="#v:many" class="selflink">#</a></p><div class="doc"><p>The <code><a href="Lessons-Lesson04.html#v:many" title="Lessons.Lesson04">many</a></code> parser runs another parser repeatedly on the input.
It succeeds even if the inner parser matches zero times.</p><p>The helper function <code>many'</code> carries an accumulator <code>acc</code> that collects results.</p><p><code>v</code> represents the value returned by the inner parser and <code>r</code> represents the remaining input string after parsing.</p></div></div><div class="top"><p class="src"><a id="v:many1" class="def">many1</a> :: <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> a -> <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> [a] <a href="src/Lessons.Lesson04.html#many1" class="link">Source</a> <a href="#v:many1" class="selflink">#</a></p><div class="doc"><p>The <code><a href="Lessons-Lesson04.html#v:many1" title="Lessons.Lesson04">many1</a></code> parser behaves like <code><a href="Lessons-Lesson04.html#v:many" title="Lessons.Lesson04">many</a></code>, but it requires at least one successful parse.
If the input does not contain any valid elements, it fails.</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>parseString ""
</code></strong>Left "At least on value required"
<code class="prompt">>>> </code><strong class="userinput"><code>parseString "afds"
</code></strong>Right ("afds","")
<code class="prompt">>>> </code><strong class="userinput"><code>parseString "afds5345"
</code></strong>Right ("afds","5345")
</pre></div></div><div class="top"><p class="src"><a id="v:parseString" class="def">parseString</a> :: <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> String <a href="src/Lessons.Lesson04.html#parseString" class="link">Source</a> <a href="#v:parseString" class="selflink">#</a></p><div class="doc"><p>This parser combines everything we have built so far.
It parses one or more letters from the beginning of the input string.
It succeeds if at least one letter is found, and returns the collected string.</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>parseString "afds"
</code></strong>Right ("afds","")
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>parseString "afds5345"
</code></strong>Right ("afds","5345")
</pre><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>parseString "afds 5345"
</code></strong>Right ("afds"," 5345")
</pre></div></div><div class="top"><p class="src"><a id="v:pmap" class="def">pmap</a> :: (a -> b) -> <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> a -> <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> b <a href="src/Lessons.Lesson04.html#pmap" class="link">Source</a> <a href="#v:pmap" class="selflink">#</a></p><div class="doc"><p>The <code><a href="Lessons-Lesson04.html#v:pmap" title="Lessons.Lesson04">pmap</a></code> function allows us to transform the result produced by a parser without changing how that parser actually reads the input string.</p><p>A parser of type 'Parser a' returns either:
<code>Left</code> with an error message if parsing fails, or
'Right (v, r)' where <code>v</code> is the parsed value and <code>r</code> is the remaining input.</p><p><code><a href="Lessons-Lesson04.html#v:pmap" title="Lessons.Lesson04">pmap</a></code> takes a transformation function <code>f :: a -> b</code> and a parser <code>p :: Parser a</code>,
and produces a new parser <code>Parser b</code> that behaves just like <code>p</code> but applies <code>f</code>
to the successfully parsed value before returning it.</p><p>The overall structure of the result (<code>Left</code> or <code>Right</code>, plus the remaining input)
stays exactly the same — only the parsed value itself is modified.</p><p>For example, if <code>many1 parseDigit</code> returns <code>Right ("123", "")</code>,
then <code>pmap read (many1 parseDigit)</code> will return <code>Right (123, "")</code>.</p><p>This pattern is the same idea as <code>map</code> for Lists: map over the value
inside a container (in this case, the parsing context).</p></div></div><div class="top"><p class="src"><a id="v:parseInteger" class="def">parseInteger</a> :: <a href="Lessons-Lesson04.html#t:Parser" title="Lessons.Lesson04">Parser</a> Integer <a href="src/Lessons.Lesson04.html#parseInteger" class="link">Source</a> <a href="#v:parseInteger" class="selflink">#</a></p><div class="doc"><p>This parser reads one or more digits from the input string and converts them into an <code>Integer</code>.
It demonstrates how to combine parsing ('many1 parseDigit') with transformation ('pmap read').</p><pre class="screen"><code class="prompt">>>> </code><strong class="userinput"><code>parseInteger "3423432gfhg"
</code></strong>Right (3423432,"gfhg")
</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>