Created
February 3, 2018 20:57
-
-
Save neongreen/e6eee632b769174a276c25b95c245ebe to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Dirt Cheap Haskell: Library</title><id>https://dirtcheaphaskell.io#library</id><updated>2017-11-02T00:00:00Z</updated><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://dirtcheaphaskell.io#library"/><entry><id>2017-11-02-editor-integration</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Haskell integration with editors</title><updated>2017-11-02T00:00:00Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html"><details class="qa-session"><summary><span class="qa-header"><span id="2017-11-02-editor-integration" class="qa-title"><a href="#2017-11-02-editor-integration">Haskell integration with editors</a></span><time class="qa-time">2017-11-02</time></span></summary><div class="qa-message qa-role-client qa-msg-highlight"><p class="qa-author"><span class="qa-username">Client</span></p><div class="qa-content"><p>Do any non-Vim/Emacs editors have good Haskell integration?</p> | |
</div></div><div class="qa-message qa-role-consultant qa-msg-casual"><p class="qa-author"><a href="https://github.com/int-index"><img src="https://avatars1.githubusercontent.com/u/4061728?v=4&amp;s=128" class="qa-userpic"><span class="qa-username">Vladislav Zavialov</span></a></p><div class="qa-content"><p>I would go as far as to say that there&#39;s no good editor integration | |
for Haskell at all. There&#39;s <code>ghc-mod</code> and the ecosystem around it, but | |
it stops being usable as soon as the project is big enough. It&#39;s just | |
too slow. And lots of Haskell tooling suffers from the issue that | |
there&#39;s no good package with the Haskell AST (there&#39;s | |
<code>haskell-src-exts</code>, but it&#39;s just not what the compiler uses, and the | |
discrepancies are often noticable). Another story is integration with | |
build systems... Honestly, at one point I gave up and decided not to | |
use Haskell tooling, it&#39;s broken.</p> | |
<p><a href="https://github.com/alanz">@alanz</a> is doing an immense amount of work to fix that.</p> | |
</div></div><div class="qa-message qa-role-consultant qa-msg-casual"><p class="qa-author"><a href="https://github.com/neongreen"><img src="https://avatars2.githubusercontent.com/u/1523306?v=4&amp;s=128" class="qa-userpic"><span class="qa-username">Artyom Kazak</span></a></p><div class="qa-content"><p>NB: I heard from a coworker that Sublime can be set up to work as well | |
as Emacs; if you consider Emacs&#39;s integration good, I could ask | |
him for details about his Sublime setup if you&#39;re interested.</p> | |
</div></div><div class="qa-message qa-role-consultant qa-msg-casual"><p class="qa-author"><a href="https://github.com/int-index"><img src="https://avatars1.githubusercontent.com/u/4061728?v=4&amp;s=128" class="qa-userpic"><span class="qa-username">Vladislav Zavialov</span></a></p><div class="qa-content"><p>There were discussions in the GHC mailing list about defining an | |
external AST for GHC which could be used by various tooling. They also | |
plan to apply the principles from the <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2016/11/trees-that-grow.pdf">“Trees That Grow” paper</a>, | |
which is an amazing idea. All of it is happening right now, and | |
Haskell will get the tooling it deserves sooner or later (but, sadly, | |
&quot;later&quot; sounds more realistic).</p> | |
<p>Anyway, I&#39;d still recommend <a href="https://hackage.haskell.org/package/hasktags"><code>hasktags</code></a> to generate tags. | |
Although it doesn&#39;t work very good either (sometimes it misses some | |
definitions, sometimes it indexes non-definitions), but it works 90% | |
of the time and &quot;Jump to definition&quot; is just something that gives an | |
immense productivity boost (even if a bit broken).</p> | |
<p>One important caveat is that you can&#39;t jump to definitions generated | |
by Template Haskell. That&#39;s quite obvious in retrospect, because | |
<code>hasktags</code> doesn&#39;t run the compile-time code, but might be a bit | |
disappointing when you can&#39;t jump to a lens generated by <code>makeLenses</code> | |
or something like that.</p> | |
<p>And if you use Stack as your build tool, just having <code>stack build --file-watch</code> in a terminal window next to the editor is often | |
sufficient.</p> | |
<p>Most of the people who worked on tooling such as <code>haskell-mode</code>, | |
<code>ghc-mod</code>, and <code>ide-backend</code>, decided to consolidate their efforts and | |
work on <a href="https://github.com/haskell/haskell-ide-engine"><code>haskell-ide-engine</code></a>. What&#39;s exciting about this is that | |
they plan to support <a href="https://microsoft.github.io/language-server-protocol">Language Server Protocol</a>. Basically, this | |
means that we&#39;ll get Haskell support in all editors that support LSP, | |
so it&#39;s going to be N+M rather than N×M.</p> | |
</div></div><div class="qa-message qa-role-client qa-msg-casual"><p class="qa-author"><span class="qa-username">Client</span></p><div class="qa-content"><p>Ok cool, I’ll try out <code>hasktags</code> tomorrow. I’ll also try | |
<code>haskell-ide-engine</code> with VS Code tomorrow, looks like that’s working?</p> | |
</div></div><div class="qa-message qa-role-consultant qa-msg-casual"><p class="qa-author"><a href="https://github.com/int-index"><img src="https://avatars1.githubusercontent.com/u/4061728?v=4&amp;s=128" class="qa-userpic"><span class="qa-username">Vladislav Zavialov</span></a></p><div class="qa-content"><p>Things are working up until they break, which might be when (1) the | |
project is too big and the tooling gets painfully slow to use, (2) you | |
need an obscure language extension that wreaks havoc on the tooling.</p> | |
<p>Especially if it&#39;s an extension implemented in the latest compiler | |
version and it&#39;s a syntactic addition. When <code>-XLambdaCase</code> was | |
introduced, everything <code>haskell-src-exts</code>-based just stopped working – | |
that&#39;s just one example.</p> | |
</div></div></details></content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://dirtcheaphaskell.io#2017-11-02-editor-integration"/></entry><entry><id>2017-11-02-monad-transformers</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Monad transformers</title><updated>2017-11-02T00:00:00Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html"><details class="qa-session"><summary><span class="qa-header"><span id="2017-11-02-monad-transformers" class="qa-title"><a href="#2017-11-02-monad-transformers">Monad transformers</a></span><time class="qa-time">2017-11-02</time></span></summary><div class="qa-message qa-role-client qa-msg-highlight"><p class="qa-author"><span class="qa-username">Client</span></p><div class="qa-content"><p>I&#39;ve got a kinda generic question. How do monad transformers work?</p> | |
</div></div><div class="qa-message qa-role-consultant qa-msg-casual"><p class="qa-author"><a href="https://github.com/int-index"><img src="https://avatars1.githubusercontent.com/u/4061728?v=4&amp;s=128" class="qa-userpic"><span class="qa-username">Vladislav Zavialov</span></a></p><div class="qa-content"><p>Well, the reason to use monad transformers is to get the <code>Monad</code> | |
instances automatically. For example, there&#39;s no runtime difference | |
between <code>a -&gt; IO b</code> and <code>ReaderT a IO b</code>, but the latter has a <code>Monad</code> | |
instance, whereas the former doesn&#39;t. Actually, that&#39;s it.</p> | |
<p>Of course, we could use a function instead:</p> | |
<pre><code class="language-haskell">state -&gt; env -&gt; IO (Either exc (a, state)) | |
</code></pre> | |
<p>But we want a <code>(&gt;&gt;=)</code> that does all the plumbing, and to get this we | |
express the same thing as a transformers stack:</p> | |
<pre><code class="language-haskell">StateT state (ReaderT env (ExceptT exc IO)) a | |
</code></pre> | |
</div></div><div class="qa-message qa-role-client qa-msg-casual"><p class="qa-author"><span class="qa-username">Client</span></p><div class="qa-content"><p>Ok, that makes sense.</p> | |
<p>I’ll read that chapter of @bitemyapp’s book on that and ask you if I | |
have any specific questions.</p> | |
</div></div><div class="qa-message qa-role-consultant qa-msg-casual"><p class="qa-author"><a href="https://github.com/int-index"><img src="https://avatars1.githubusercontent.com/u/4061728?v=4&amp;s=128" class="qa-userpic"><span class="qa-username">Vladislav Zavialov</span></a></p><div class="qa-content"><p>And we couldn&#39;t define a <code>Monad</code> instance for <code>a -&gt; IO b</code> because it&#39;s | |
unclear whether we want it to behave as <code>ReaderT a IO b</code> or <code>Reader a (IO b)</code>. So the structure of transformers layers tells the compiler | |
how deep we want <code>(&gt;&gt;=)</code> to inspect the structure of the types.</p> | |
<p>(Well, actually, <code>a -&gt; IO b</code> has a <code>Monad</code> instance and it&#39;s indeed | |
equivalent to <code>Reader a (IO b)</code> rather than <code>ReaderT a IO b</code>.)</p> | |
</div></div></details></content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://dirtcheaphaskell.io#2017-11-02-monad-transformers"/></entry><entry><id>2017-11-02-servant-yesod</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Servant vs Yesod</title><updated>2017-11-02T00:00:00Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html"><details class="qa-session"><summary><span class="qa-header"><span id="2017-11-02-servant-yesod" class="qa-title"><a href="#2017-11-02-servant-yesod">Servant vs Yesod</a></span><time class="qa-time">2017-11-02</time></span></summary><div class="qa-message qa-role-client qa-msg-highlight"><p class="qa-author"><span class="qa-username">Client</span></p><div class="qa-content"><p>How does Servant compare to Yesod?</p> | |
</div></div><div class="qa-message qa-role-consultant qa-msg-casual"><p class="qa-author"><a href="https://github.com/int-index"><img src="https://avatars1.githubusercontent.com/u/4061728?v=4&amp;s=128" class="qa-userpic"><span class="qa-username">Vladislav Zavialov</span></a></p><div class="qa-content"><p>The primary philosophical difference is that Servant tries to do | |
everything using type-level tricks, while Yesod uses Template Haskell | |
a lot. The code looks very different with these frameworks because of | |
that. What&#39;s common between them is that they&#39;re both <code>wai</code>-based, | |
meaning they can run atop any <code>wai</code>-compatible server (<code>warp</code> or | |
<code>warp-tls</code>), and that&#39;s great. I recommend against frameworks that | |
aren&#39;t <code>wai</code>-based (this includes Snap and Happstack) because <code>warp</code> | |
is a great web server, it&#39;s performant and configurable. Now, I&#39;m not | |
going to give a point-by-point comparison for Servant and Yesod | |
because they&#39;re just so different that having such a list might be | |
misleading. For instance, they both support type-safe routing, but | |
it&#39;s done in wildly different ways.</p> | |
<p>I&#39;d say it&#39;s useful to know both. If you implement a web API that | |
talks to the front-end using JSON, I recommend Servant. If you want a | |
multi-page web-app that has user authorization and stuff like this, | |
Yesod is the path of least resistance. And since both of them are | |
<code>wai</code>-based (did I mention it&#39;s great? well, here&#39;s another reason | |
why) you can embed a Servant website as a subsite for Yesod, and vice | |
versa, you can run a Yesod website as part of a Servant API.</p> | |
</div></div><div class="qa-message qa-role-client qa-msg-casual"><p class="qa-author"><span class="qa-username">Client</span></p><div class="qa-content"><p>I have more experience with Yesod (am a contributor, read a lot of the | |
code) but I’m finding that I’m just ripping out most of it – so I’ll | |
give Servant a try.</p> | |
<p>I’m a little worried it looks too complex to introduce to beginners.</p> | |
</div></div><div class="qa-message qa-role-consultant qa-msg-casual"><p class="qa-author"><a href="https://github.com/int-index"><img src="https://avatars1.githubusercontent.com/u/4061728?v=4&amp;s=128" class="qa-userpic"><span class="qa-username">Vladislav Zavialov</span></a></p><div class="qa-content"><p>It definitely is very complex on the inside, if you try to look at the | |
definitions they&#39;re monstrous – but I&#39;d claim that using it isn&#39;t hard | |
at all. Those definitions are so complex precisely to allow for | |
elegant code that uses them, they try to hide a lot of complexity.</p> | |
<p>Of course, it doesn&#39;t help that Haskell doesn&#39;t have good facilities | |
for type-level programming. In a language where functions are promoted | |
and there&#39;s proper relevant quantification (might be getting a bit | |
technical here), Servant could be implemented much nicer.</p> | |
</div></div></details></content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://dirtcheaphaskell.io#2017-11-02-servant-yesod"/></entry></feed> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment