-
Notifications
You must be signed in to change notification settings - Fork 0
/
2014-05-19-bayhac-2014.html
117 lines (108 loc) · 15.6 KB
/
2014-05-19-bayhac-2014.html
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>sencjw - BayHac2014</title>
<link rel="stylesheet" type="text/css" href="../css/normalize.css" />
<link rel="stylesheet" type="text/css" href="../css/default.css" />
<link rel="stylesheet" type="text/css" href="../css/syntax.css" />
<link href="../atom.xml" type="application/atom+xml" rel="alternate" />
<link href="../feed.rss" type="application/rss+xml" rel="alternate" />
</head>
<body>
<div class="content">
<header>
<h1>sencjw</h1>
<h2>a place I put stuff</h2>
</header>
<nav>
<ul>
<li><a href="../">Home</a></li>
<li><a href="../archive.html">Blog Archive</a></li>
<li><a href="../contact.html">Contact</a></li>
<li><a href="../interviews.html">Interviews</a></li>
<li><a href="../talks.html">Talks</a></li>
<li><a href="../the_square_root_of_christmas.html">The Square Root of Christmas</a></li>
<li><a href="../transparent_web.html">The Transparent Web (book)</a></li>
<li><a href="../writings.html">Writings</a></li>
</ul>
</nav>
<main>
<article>
<header>
<h1>BayHac2014</h1>
<p>
Posted on May 19, 2014
</p>
</header>
<p>I’m making my way back from <a href="http://www.haskell.org/haskellwiki/BayHac2014">BayHac 2014</a> as I write this but I wanted to put down a few thoughts while they’re still fresh.</p>
<h2 id="friday">Friday</h2>
<p>The hackathon started out with a talk on Pipes by Gabriel Gonzalez and then one on Free Monads by Dan Piponi. Both were excellent. And <em>excellent</em> here means that I think they were both the most lucid explanations of their respective topic that I’ve yet seen.</p>
<p>Gabriel’s talk really helped to solidify my understanding of where pipes sit relative to <a href="http://hackage.haskell.org/package/conduit-1.0.15">conduit</a>, the other streaming-data library that I’m familiar with. The emphasis in the pipes talk was on the intuition behind the <a href="http://hackage.haskell.org/package/pipes-4.1.2/docs/Pipes.html#t:ListT"><code>ListT</code></a> type and the <a href="http://hackage.haskell.org/package/pipes-4.1.2/docs/Pipes.html#t:yield"><code>yield</code></a> and <a href="http://hackage.haskell.org/package/pipes-4.1.2/docs/Pipes.html#t:await"><code>await</code></a> functions.</p>
<p>Dan Piponi spoke on free monads, <a href="https://docs.google.com/file/d/0B51SFgxqMDS-NDBOX0ZDdW52dEE/edit">Free, but not as in beer or speech</a> (<a href="https://plus.google.com/u/0/events/cu5t5s2g14t4fqmapft5bcatqeg">video</a>), by first starting with an algebraic structure called a <em>magma</em>, which is simply a single, closed binary operation on a set:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">class</span> <span class="dt">Magma</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb1-2" title="2"><span class="ot"> o ::</span> a <span class="ot">-></span> a <span class="ot">-></span> a</a></code></pre></div>
<p>Next he suggested the idea of the “least special magma.” We want to capture the idea that we can do this binary operation, and that we have things that are part of the set (the <code>a</code> above). This leads us to a tree:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="kw">data</span> <span class="dt">FreeMagma</span> a <span class="fu">=</span> <span class="dt">Var</span> a</a>
<a class="sourceLine" id="cb2-2" title="2"> <span class="fu">|</span> <span class="dt">Tree</span> (<span class="dt">FreeMagma</span> a) (<span class="dt">FreeMagma</span> a)</a>
<a class="sourceLine" id="cb2-3" title="3"><span class="kw">instance</span> <span class="dt">Magma</span> (<span class="dt">FreeMagma</span> a) <span class="kw">where</span></a>
<a class="sourceLine" id="cb2-4" title="4"> o <span class="fu">=</span> <span class="dt">Tree</span></a></code></pre></div>
<p>So the idea is that we’re combining two subexpressions (which could be just <code>Var a</code>, of course) and that’s it. The <em>structure</em> embodies the operation that we’re interested in. I don’t want to recapitulate the talk, but here’s one last slide. We can kinda crawl the structure that we’ve set up in order to evaluate the free magma:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1"><span class="ot">interpretMagma ::</span> <span class="dt">Magma</span> b <span class="ot">=></span> (a <span class="ot">-></span> b) <span class="ot">-></span> (<span class="dt">FreeMagma</span> a <span class="ot">-></span> b)</a>
<a class="sourceLine" id="cb3-2" title="2">interpretMagma f (<span class="dt">Var</span> a) <span class="fu">=</span> f a</a>
<a class="sourceLine" id="cb3-3" title="3">interpretMagma f (<span class="dt">Tree</span> a b) <span class="fu">=</span> interpretMagma f a <span class="ot">`o`</span> interpretMagma f b</a></code></pre></div>
<p>Evaluating this thing is really just replacing the structure with elements of our choosing according to some rule.</p>
<p>The talk goes on (and the plot thickens!) by moving into free monoids and then, free monads. It was a great introduction!</p>
<h2 id="saturday">Saturday</h2>
<p>Saturday I was able to attend part of the <a href="http://yesodweb.com/">Yesod</a> class (and I’m already a little familiar with Yesod), so the introduction was mostly things I’ve covered on my own. As an aside, I was <em>scheduled</em> for the Lens class and I say scheduled because BayHac was <em>very</em> popular and classes were randomly assigned based up on interest and space. Most classes were packed.</p>
<p>The lens introduction by Shachaf Ben-Kiki was great. I’ve been reading up on these a lot lately so for me the ground had been prepared in just the right way for me to get a lot out of this. Shachaf moved at a brisk pace, whether through practice or sheer type-signature-fu, he hammered out types and definitions for things like lenses and traversals about as fast as I type prose. This class really lit a bulb for me about why the types work the way that they do for lenses. My very hand-wavey summary of this was that a lens is like having a writer monad “logging” the parts of some structure you’re interested in walking over. But rather than being interested in the <em>value</em> that the writer produces it’s the <em>log</em> that you want.</p>
<p><em>Caution, the following is based on my own emerging understanding of Lenses. Please pardon any errors (and I welcome corrections).</em></p>
<p>What started to make sense for me was the connection between <a href="https://hackage.haskell.org/package/lens-4.1.2/docs/Control-Lens-Setter.html#v:over">over</a>, <a href="http://hackage.haskell.org/package/base-4.7.0.0/docs/Data-Traversable.html#v:traverse">traverse</a>, and <a href="http://hackage.haskell.org/package/lens-4.1.2.1/docs/Control-Lens-Lens.html#t:Lens">Lens</a>.</p>
<p>First, looking at traverse, which has the type:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="fu">traverse</span></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="ot"> ::</span> (<span class="dt">Traversable</span> t, <span class="dt">Applicative</span> f) <span class="ot">=></span> (a <span class="ot">-></span> f b) <span class="ot">-></span> t a <span class="ot">-></span> f (t b)</a></code></pre></div>
<p>you can think of it as a sort of generalized <a href="http://hackage.haskell.org/package/base-4.7.0.0/docs/Data-List.html#v:map">map</a> (I do). We know the <code>f</code> above is a Functor because:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" title="1"><span class="kw">class</span> <span class="dt">Functor</span> f <span class="ot">=></span> <span class="dt">Applicative</span> f <span class="kw">where</span> <span class="fu">...</span></a></code></pre></div>
<p>So, picking an Applicative, say the <a href="http://hackage.haskell.org/package/transformers-0.4.1.0/docs/Data-Functor-Identity.html#t:Identity">Identity</a> Applicative, you can write something like map:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb6-1" title="1"><span class="ot">map' ::</span> <span class="dt">Traversable</span> t <span class="ot">=></span> (a <span class="ot">-></span> b) <span class="ot">-></span> t a <span class="ot">-></span> t b</a>
<a class="sourceLine" id="cb6-2" title="2">map' f <span class="fu">=</span> runIdentity <span class="fu">.</span> <span class="fu">traverse</span> (<span class="dt">Identity</span> <span class="fu">.</span> f)</a></code></pre></div>
<p>notice how we’re sort of “packaging” up the result of the function in a dummy Applicative (<code>runIdentity . Identity == id</code>), which we then immediately discard. This is exactly the sort of sleight of hand that we need for Lens:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" title="1"><span class="kw">type</span> <span class="dt">Lens</span> s t a b <span class="fu">=</span> <span class="kw">forall</span> f<span class="fu">.</span> <span class="dt">Functor</span> f <span class="ot">=></span> (a <span class="ot">-></span> f b) <span class="ot">-></span> s <span class="ot">-></span> f t</a></code></pre></div>
<p>Notice how the <a href="https://hackage.haskell.org/package/lens-4.1.2/docs/Control-Lens-Getter.html#v:view">view</a> function does something really similar:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" title="1"><span class="ot">view ::</span> <span class="dt">MonadReader</span> s m <span class="ot">=></span> <span class="dt">Getting</span> a s a <span class="ot">-></span> m a</a>
<a class="sourceLine" id="cb8-2" title="2"><span class="co">-- re-written with definition of Getting</span></a>
<a class="sourceLine" id="cb8-3" title="3"><span class="ot">view ::</span> <span class="dt">MonadReader</span> s m <span class="ot">=></span> (a <span class="ot">-></span> <span class="dt">Const</span> a a) <span class="ot">-></span> s <span class="ot">-></span> <span class="dt">Const</span> a s <span class="ot">-></span> m a</a></code></pre></div>
<p><code>Const</code> is similar to <code>Identity</code> in that it has a “weird” definition:</p>
<p>`<code>haskell instance Functor (Const m) where fmap _ (Const v) = Const v -- the function doesn't matter!</code></p>
<p>putting that all together (and I’m still a bit fuzzy on how the types work out on these) gives you something that takes a Lens of some structure but then <em>ignores</em> that structure (the <code>s</code> in the <code>Const a s</code>). So you’re getting your structure with the value picked out, but then ignoring the structure (and leaving just the value you’re interested in).</p>
<p>That’s really handwavey, but here’s an example:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" title="1"><span class="kw">data</span> <span class="dt">Person</span> <span class="fu">=</span> <span class="dt">Person</span> {<span class="ot"> fn ::</span> <span class="dt">String</span> ,<span class="ot"> ln ::</span> <span class="dt">String</span> }</a>
<a class="sourceLine" id="cb9-2" title="2"><span class="co">-- e.g. fn (Person "Chris" "Wilson") == "Chris")</span></a></code></pre></div>
<p>Now I can make a <code>Lens</code> of <code>fn</code> by specifying my own getter and setter functions:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb10-1" title="1">fnLens <span class="fu">=</span> lens fn (\(<span class="dt">Person</span> a b) v <span class="ot">-></span> <span class="dt">Person</span> v b)</a></code></pre></div>
<p>Now I can use that to access the <code>Person</code> structure:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb11-1" title="1">view fnLens (<span class="dt">Person</span> <span class="st">"Chris"</span> <span class="st">"Wilson"</span>)</a>
<a class="sourceLine" id="cb11-2" title="2"><span class="co">-- "Chris"</span></a></code></pre></div>
<p>And the type would be something like:</p>
<pre><code>view :: (a -> Const a a) -- as above
-> s
-> Const a s
-> m a
fnLens :: (String -> Const String String) -- subbing in types
-> Person
-> Const String Person
view fnLens :: MonadReader Person m => m String</code></pre>
<p>The above type signature is a bit wonky, but I think it captures what’s happening as the types unify. So it all boils down to something that extracts a <code>String</code> from a <code>Person</code>. But the intuition that is starting to grow for me is that Lenses let you use a carefully-chosen (i.e. <code>Const</code>) <code>Functor</code> to “smuggle” a value out of a bigger structure.</p>
<h2 id="sunday">Sunday</h2>
<p>I spent a lot of time on Sunday working on Joe Nelson’s <a href="https://github.com/begriffs/haskell-vim-now">haskell-vim-now</a> one-line Haskell Vim installer. Lots of people were excited about the prospect of having an easy-to-install Vim mode. I think that this has made a lot of progress. If you like Vim and want to do Haskell development, go install it now. If you want to just install it here, just run this:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb13-1" title="1"><span class="ex">curl</span> -o - https://raw.githubusercontent.com/begriffs/haskell-vim-now/master/install.sh <span class="kw">|</span> <span class="fu">bash</span></a></code></pre></div>
<p>But please see the <a href="https://github.com/begriffs/haskell-vim-now/blob/master/README.md">README</a> for keybindings and general tips on use. Also, if there is anything that you’d like to see included or revised, you are <a href="https://github.com/begriffs/haskell-vim-now/issues">invited to submit an issue</a>.</p>
<p>I also spent some time talking with the <a href="https://snowdrift.coop">Snowdrift.coop</a> developers. This is a funding platform that seeks to crowdfund ongoing Free/Libre/Open Source projects. They have a nice <a href="https://snowdrift.coop/p/snowdrift/w/intro">intro</a>. The Haskell angle here is that this is a Yesod app: source <a href="https://github.com/dlthomas/snowdrift">on Github</a> and <a href="https://gitorious.org/snowdrift/snowdrift/source/6b587c9c176aa24917c7403dbadd3778e17d08b4:">on Gitorious</a>.</p>
<h2 id="summary">Summary</h2>
<p>BayHac was a great experince! I got to meet with a bunch of people that I had only been following online so far. And I think it really fired me up to write more production Haskell. I’m even looking for ways to integrate it into Bendyworks’ development.</p>
</article>
</main>
</div>
</body>
</html>