https instead of http

fixes #95
This commit is contained in:
Joel Kaasinen
2023-12-11 17:40:05 +02:00
parent e28cf0bce9
commit 095bbac0cc
4 changed files with 12 additions and 12 deletions
+8 -8
View File
@@ -1372,7 +1372,7 @@ square ==> * ==> * ==> 16
<span id="cb94-12"><a href="#cb94-12" aria-hidden="true" tabindex="-1"></a><span class="op">==&gt;</span> <span class="fu">seq</span> <span class="dv">6</span> (foldl&#39; (<span class="op">+</span>) <span class="dv">6</span> [])</span>
<span id="cb94-13"><a href="#cb94-13" aria-hidden="true" tabindex="-1"></a><span class="op">==&gt;</span> foldl&#39; (<span class="op">+</span>) <span class="dv">6</span> []</span>
<span id="cb94-14"><a href="#cb94-14" aria-hidden="true" tabindex="-1"></a><span class="op">==&gt;</span> <span class="dv">6</span></span></code></pre></div>
<p>We won’t dive deeper into this subject on this course, but it’s important that you’re aware that <code>seq</code> exists. You can find more about <code>seq</code> on <a href="https://wiki.haskell.org/Seq">the Haskell Wiki</a> and learn more about when it is necessary to add strictness in <a href="https://book.realworldhaskell.org/read/profiling-and-optimization.html">Real World Haskell</a>. Often it’s nicer to use <em>bang patterns</em> instead of <code>seq</code>, as discussed by <a href="https://www.fpcomplete.com/blog/2017/09/all-about-strictness/">FPComplete</a> and <a href="http://book.realworldhaskell.org/read/profiling-and-optimization.html">Real World Haskell</a>.</p>
<p>We won’t dive deeper into this subject on this course, but it’s important that you’re aware that <code>seq</code> exists. You can find more about <code>seq</code> on <a href="https://wiki.haskell.org/Seq">the Haskell Wiki</a> and learn more about when it is necessary to add strictness in <a href="https://book.realworldhaskell.org/read/profiling-and-optimization.html">Real World Haskell</a>. Often it’s nicer to use <em>bang patterns</em> instead of <code>seq</code>, as discussed by <a href="https://www.fpcomplete.com/blog/2017/09/all-about-strictness/">FPComplete</a> and <a href="https://book.realworldhaskell.org/read/profiling-and-optimization.html">Real World Haskell</a>.</p>
</section>
<section id="newtype-declarations" data-number="2.7">
<h2 data-number="10.7"><span class="header-section-number">10.7</span> Newtype Declarations</h2>
@@ -3769,7 +3769,7 @@ None of the above
<section id="writing-a-http-server-wai-and-warp" data-number="6.3">
<h2 data-number="14.3"><span class="header-section-number">14.3</span> Writing a HTTP Server: WAI and Warp</h2>
<p>Sometimes it feels like everything in the world happens over <a href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol">HTTP</a> and <a href="https://en.wikipedia.org/wiki/Web_API">Web Apis</a>. Your web browser, your smartphone apps, <a href="https://developer.nordeaopenbanking.com/">your bank</a>, <a href="https://tools.ietf.org/html/rfc2324">your coffee pot</a>, <a href="https://support.ring.com/hc/en-us/articles/205385394-The-Protocols-and-Ports-Used-by-Ring-Devices">and even your doorbell</a>, all talk to servers using the HTTP protocol.</p>
<p>Let’s look at how we can set up a simple HTTP server in Haskell. The standard low level components for this are called <a href="https://hackage.haskell.org/package/wai-3.2.3/docs/Network-Wai.html">WAI</a> and <a href="http://hackage.haskell.org/package/warp-3.3.14">Warp</a>. WAI, the Web Application Interface gives us a way to define how HTTP requests are handled. Warp is a simple HTTP server that runs the logic we have defined using WAI. That probably sounds a bit abstract right now, but a simple example will help.</p>
<p>Let’s look at how we can set up a simple HTTP server in Haskell. The standard low level components for this are called <a href="https://hackage.haskell.org/package/wai-3.2.3/docs/Network-Wai.html">WAI</a> and <a href="https://hackage.haskell.org/package/warp-3.3.14">Warp</a>. WAI, the Web Application Interface gives us a way to define how HTTP requests are handled. Warp is a simple HTTP server that runs the logic we have defined using WAI. That probably sounds a bit abstract right now, but a simple example will help.</p>
<p>The file <a href="https://github.com/moocfi/haskell-mooc/blob/master/exercises/Examples/HelloServer.hs"><code>exercises/Examples/HelloServer.hs</code></a> implements a HTTP server that always responds with “Hello World!”. You can try it out by going to the <code>exercises/Examples</code> directory and running it with <code>stack runhaskell HelloServer.hs</code>. After that you can visit <a href="http://localhost:3421" class="uri">http://localhost:3421</a> in your browser to see the response from the server.</p>
<div class="sourceCode" id="cb324"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb324-1"><a href="#cb324-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Examples.HelloServer</span> <span class="kw">where</span></span>
<span id="cb324-2"><a href="#cb324-2" aria-hidden="true" tabindex="-1"></a></span>
@@ -3788,12 +3788,12 @@ None of the above
<span id="cb324-15"><a href="#cb324-15" aria-hidden="true" tabindex="-1"></a><span class="ot">application ::</span> <span class="dt">Application</span></span>
<span id="cb324-16"><a href="#cb324-16" aria-hidden="true" tabindex="-1"></a>application request respond <span class="ot">=</span></span>
<span id="cb324-17"><a href="#cb324-17" aria-hidden="true" tabindex="-1"></a> respond (responseLBS status200 [] (BL.pack <span class="st">&quot;Hello World!&quot;</span>))</span></code></pre></div>
<p>Let’s look at the types in this example. There’s a lot going on here. First off, <code>Application</code> is a <em>type alias</em> for a thing that implements the logic of a web server. The <a href="http://hackage.haskell.org/package/warp-3.3.14/docs/Network-Wai-Handler-Warp.html#v:run"><code>run</code> function from Warp</a> can run <code>Application</code>s:</p>
<p>Let’s look at the types in this example. There’s a lot going on here. First off, <code>Application</code> is a <em>type alias</em> for a thing that implements the logic of a web server. The <a href="https://hackage.haskell.org/package/warp-3.3.14/docs/Network-Wai-Handler-Warp.html#v:run"><code>run</code> function from Warp</a> can run <code>Application</code>s:</p>
<div class="sourceCode" id="cb325"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb325-1"><a href="#cb325-1" aria-hidden="true" tabindex="-1"></a><span class="ot">run ::</span> <span class="dt">Port</span> <span class="ot">-&gt;</span> <span class="dt">Application</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</span>
<span id="cb325-2"><a href="#cb325-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Application</span> <span class="ot">=</span> <span class="dt">Request</span> <span class="ot">-&gt;</span> (<span class="dt">Response</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> <span class="dt">ResponseReceived</span>) <span class="ot">-&gt;</span> <span class="dt">IO</span> <span class="dt">ResponseReceived</span></span></code></pre></div>
<p>We’ll talk about what <code>Request</code> and <code>Response</code> are soon, but from this type we can see that an <code>Application</code> is an IO operation that takes as arguments a request of type <code>Request</code>, and an IO operation <code>respond :: Response -&gt; IO ResponseReceived</code>. Arguments like <code>respond</code> are called <em>callbacks</em> in many contexts. They allow us to call back to the library who called the application. The <code>Application</code> operation has to produce the same special <code>ResponseReceived</code> type that <code>respond</code>. You can think of this type as a token proving that <code>respond</code> was called by the <code>Application</code>.</p>
<p>That might sound intimidating: but looking at the code things are relatively simple: our <code>server</code> is an <code>Application</code> and takes two parameters: <code>request</code> and <code>respond</code>.</p>
<p>WAI uses lots of types like <code>Port</code>, <code>Request</code>, <code>Response</code>, <code>Status</code> to represent HTTP concepts. It’s useful to look these up in the documentation when you bump into them. For example <a href="http://hackage.haskell.org/package/warp-3.3.14/docs/Network-Wai-Handler-Warp.html#t:Port"><code>Port</code> is just an alias for <code>Int</code></a>. As another example, we can see the <a href="https://hackage.haskell.org/package/wai-3.2.2.1/docs/Network-Wai.html#v:responseLBS"><code>responseLBS</code> function</a> has the type</p>
<p>WAI uses lots of types like <code>Port</code>, <code>Request</code>, <code>Response</code>, <code>Status</code> to represent HTTP concepts. It’s useful to look these up in the documentation when you bump into them. For example <a href="https://hackage.haskell.org/package/warp-3.3.14/docs/Network-Wai-Handler-Warp.html#t:Port"><code>Port</code> is just an alias for <code>Int</code></a>. As another example, we can see the <a href="https://hackage.haskell.org/package/wai-3.2.2.1/docs/Network-Wai.html#v:responseLBS"><code>responseLBS</code> function</a> has the type</p>
<div class="sourceCode" id="cb326"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb326-1"><a href="#cb326-1" aria-hidden="true" tabindex="-1"></a><span class="ot">responseLBS ::</span> <span class="dt">Status</span> <span class="ot">-&gt;</span> <span class="dt">ResponseHeaders</span> <span class="ot">-&gt;</span> <span class="dt">ByteString</span> <span class="ot">-&gt;</span> <span class="dt">Response</span></span></code></pre></div>
<p>where <a href="https://hackage.haskell.org/package/http-types-0.12.3/docs/Network-HTTP-Types-Status.html#t:Status"><code>Status</code> is defined in <code>Network.HTTP.Types.Status</code></a>, <a href="https://hackage.haskell.org/package/http-types-0.12.3/docs/Network-HTTP-Types-Header.html#t:ResponseHeaders"><code>ResponseHeaders</code> is a type alias for <code>[Header]</code> from <code>Network.HTTP.Types.Header</code></a>, <code>ByteString</code> is a lazy <code>ByteString</code>, and the result type <a href="https://hackage.haskell.org/package/wai-3.2.3/docs/Network-Wai.html#t:Response"><code>Response</code> is defined by <code>Network.WAI</code></a>.</p>
<p>Finally, note that we take a shortcut and use the function <code>Data.ByteString.Lazy.Char8.pack</code> to convert a <code>String</code> into a <code>ByteString</code>. This only works for ASCII text.</p>
@@ -4880,20 +4880,20 @@ AABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB
</ul></li>
<li>Abstractions
<ul>
<li>Monad transformers: <a href="http://book.realworldhaskell.org/read/monad-transformers.html">RWH</a>, <a href="https://en.wikibooks.org/wiki/Haskell/Monad_transformers">Wikibook</a></li>
<li>Monad transformers: <a href="https://book.realworldhaskell.org/read/monad-transformers.html">RWH</a>, <a href="https://en.wikibooks.org/wiki/Haskell/Monad_transformers">Wikibook</a></li>
<li>Free monads (advanced topic): <a href="https://www.haskellforall.com/2012/06/you-could-have-invented-free-monads.html">blog</a></li>
<li>Lenses (advanced topic): <a href="https://hackage.haskell.org/package/lens-tutorial-1.0.3/docs/Control-Lens-Tutorial.html">tutorial</a> <a href="http://oleg.fi/gists/posts/2017-04-18-glassery.html">glassery</a></li>
<li>Lenses (advanced topic): <a href="https://hackage.haskell.org/package/lens-tutorial-1.0.3/docs/Control-Lens-Tutorial.html">tutorial</a> <a href="https://oleg.fi/gists/posts/2017-04-18-glassery.html">glassery</a></li>
<li><a href="https://bartoszmilewski.com/">Bartosz Milewski</a> covers lots of intermediate and advanced topics on his blog</li>
</ul></li>
<li>Tooling
<ul>
<li>Using <a href="https://www.haskell.org/cabal/">Cabal</a> and <a href="https://www.haskellstack.org">Stack</a> to build your own projects</li>
<li>Profiling: <a href="http://book.realworldhaskell.org/read/profiling-and-optimization.html">RWH</a>, <a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html">GHC</a></li>
<li>Profiling: <a href="https://book.realworldhaskell.org/read/profiling-and-optimization.html">RWH</a>, <a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html">GHC</a></li>
<li><a href="https://github.com/ndmitchell/hlint#readme">Hlint</a></li>
</ul></li>
<li>Libraries
<ul>
<li>Parsec (parsing): <a href="http://book.realworldhaskell.org/read/using-parsec.html">RWH</a></li>
<li>Parsec (parsing): <a href="https://book.realworldhaskell.org/read/using-parsec.html">RWH</a></li>
<li>Scotty (simple web framework), Aeson (json): <a href="https://seanhess.github.io/2015/08/19/practical-haskell-json-api.html">blog</a></li>
<li><a href="https://haskell-servant.github.io/">Servant</a> (fancy web framework with phantom types)</li>
</ul></li>