mirror of
https://github.com/iritmaximus/haskell.git
synced 2026-10-12 19:13:39 +03:00
+8
-8
@@ -1372,7 +1372,7 @@ square ==> * ==> * ==> 16
|
||||
<span id="cb94-12"><a href="#cb94-12" aria-hidden="true" tabindex="-1"></a><span class="op">==></span> <span class="fu">seq</span> <span class="dv">6</span> (foldl' (<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">==></span> foldl' (<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">==></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">"Hello World!"</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">-></span> <span class="dt">Application</span> <span class="ot">-></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">-></span> (<span class="dt">Response</span> <span class="ot">-></span> <span class="dt">IO</span> <span class="dt">ResponseReceived</span>) <span class="ot">-></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 -> 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">-></span> <span class="dt">ResponseHeaders</span> <span class="ot">-></span> <span class="dt">ByteString</span> <span class="ot">-></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>
|
||||
|
||||
Reference in New Issue
Block a user