<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	
	>
<channel>
	<title>Comments on: Doing more with length-typed vectors</title>
	<atom:link href="http://conal.net/blog/posts/doing-more-with-length-typed-vectors/feed" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog/posts/doing-more-with-length-typed-vectors</link>
	<description>Inspirations &#38; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Sat, 26 Sep 2020 21:06:12 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.17</generator>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/doing-more-with-length-typed-vectors#comment-808</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Mon, 07 Feb 2011 04:40:08 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=293#comment-808</guid>
		<description><![CDATA[&lt;p&gt;Thanks, Eyal. I had forgotten about &lt;code&gt;(&lt;$)&lt;/code&gt;.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Thanks, Eyal. I had forgotten about <code>(&lt;$)</code>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Eyal Lotem</title>
		<link>http://conal.net/blog/posts/doing-more-with-length-typed-vectors#comment-807</link>
		<dc:creator><![CDATA[Eyal Lotem]]></dc:creator>
		<pubDate>Sun, 06 Feb 2011 21:15:45 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=293#comment-807</guid>
		<description><![CDATA[&lt;p&gt;Everyone might already know this, but &lt;code&gt;(&lt;$) = fmap . const&lt;/code&gt;, so the above:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pure a = fmap (const a) units&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Can be written:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pure a = a &lt;$ units&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pure = (&lt;$ units)&lt;/code&gt;&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Everyone might already know this, but <code>(&lt;$) = fmap . const</code>, so the above:</p>

<p><code>pure a = fmap (const a) units</code></p>

<p>Can be written:</p>

<p><code>pure a = a &lt;$ units</code></p>

<p>or:</p>

<p><code>pure = (&lt;$ units)</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Conal Elliott &#187; Blog Archive &#187; A trie for length-typed vectors</title>
		<link>http://conal.net/blog/posts/doing-more-with-length-typed-vectors#comment-806</link>
		<dc:creator><![CDATA[Conal Elliott &#187; Blog Archive &#187; A trie for length-typed vectors]]></dc:creator>
		<pubDate>Tue, 01 Feb 2011 06:27:04 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=293#comment-806</guid>
		<description><![CDATA[&lt;p&gt;[...] Doing more with length-typed vectors [...]&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>[&#8230;] Doing more with length-typed vectors [&#8230;]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bas van Dijk</title>
		<link>http://conal.net/blog/posts/doing-more-with-length-typed-vectors#comment-805</link>
		<dc:creator><![CDATA[Bas van Dijk]]></dc:creator>
		<pubDate>Mon, 31 Jan 2011 19:41:31 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=293#comment-805</guid>
		<description><![CDATA[&lt;p&gt;Nice post Conal!&lt;/p&gt;

&lt;p&gt;We should realy invent a name for this pattern where we have a &quot;type level datatype&quot; (like Z and S n), an isomorphic value level GADT (like Nat) and a class that provides an overloaded constructor for this GADT (like IsNat).&lt;/p&gt;

&lt;p&gt;I used this same pattern in 3 places already:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;http://hackage.haskell.org/packages/archive/explicit-iomodes/0.6.0.2/doc/html/System-IO-ExplicitIOModes.html#t:MkIOMode&lt;/li&gt;
&lt;li&gt;http://hackage.haskell.org/packages/archive/usb-safe/0.11.0.2/doc/html/System-USB-Safe.html#t:MkTransferDirection&lt;/li&gt;
&lt;li&gt;http://hackage.haskell.org/packages/archive/usb-safe/0.11.0.2/doc/html/System-USB-Safe.html#t:MkTransferType&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I&#039;m even thinking about using some CPP hackery to abstract the pattern.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Nice post Conal!</p>

<p>We should realy invent a name for this pattern where we have a &#8220;type level datatype&#8221; (like Z and S n), an isomorphic value level GADT (like Nat) and a class that provides an overloaded constructor for this GADT (like IsNat).</p>

<p>I used this same pattern in 3 places already:</p>

<ul>
<li><a href="http://hackage.haskell.org/packages/archive/explicit-iomodes/0.6.0.2/doc/html/System-IO-ExplicitIOModes.html#t:MkIOMode" rel="nofollow">http://hackage.haskell.org/packages/archive/explicit-iomodes/0.6.0.2/doc/html/System-IO-ExplicitIOModes.html#t:MkIOMode</a></li>
<li><a href="http://hackage.haskell.org/packages/archive/usb-safe/0.11.0.2/doc/html/System-USB-Safe.html#t:MkTransferDirection" rel="nofollow">http://hackage.haskell.org/packages/archive/usb-safe/0.11.0.2/doc/html/System-USB-Safe.html#t:MkTransferDirection</a></li>
<li><a href="http://hackage.haskell.org/packages/archive/usb-safe/0.11.0.2/doc/html/System-USB-Safe.html#t:MkTransferType" rel="nofollow">http://hackage.haskell.org/packages/archive/usb-safe/0.11.0.2/doc/html/System-USB-Safe.html#t:MkTransferType</a></li>
</ul>

<p>I&#8217;m even thinking about using some CPP hackery to abstract the pattern.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Conal Elliott &#187; Blog Archive &#187; Reverse-engineering length-typed vectors</title>
		<link>http://conal.net/blog/posts/doing-more-with-length-typed-vectors#comment-804</link>
		<dc:creator><![CDATA[Conal Elliott &#187; Blog Archive &#187; Reverse-engineering length-typed vectors]]></dc:creator>
		<pubDate>Mon, 31 Jan 2011 17:53:17 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=293#comment-804</guid>
		<description><![CDATA[&lt;p&gt;[...] About      &#171; Doing more with length-typed vectors [...]&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>[&#8230;] About      &laquo; Doing more with length-typed vectors [&#8230;]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Darius Jahandarie</title>
		<link>http://conal.net/blog/posts/doing-more-with-length-typed-vectors#comment-803</link>
		<dc:creator><![CDATA[Darius Jahandarie]]></dc:creator>
		<pubDate>Mon, 31 Jan 2011 17:35:00 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=293#comment-803</guid>
		<description><![CDATA[&lt;p&gt;Or, whenever this gets finished...&lt;/p&gt;

&lt;pre&gt;
data Nat = Z &#124; S Nat -- automatically lifted to the type/kind level!

data Vec :: Nat -&gt; * -&gt; * where
  ZVec :: Vec Z a
  (:&lt;) :: a -&gt; Vec n a -&gt; Vec (S n) a

class Pure n where pureN :: a -&gt; Vec n a

instance Pure Z where pureN a = ZVec
instance Pure (S n) where pureN a = a :&lt; pureN a

instance Applicative (Vec n) where
  pure a = pureN a
  ZVec &lt;*&gt; ZVec = ZVec
  (f :&lt; fs) &lt;*&gt; (x :&lt; xs) = f x :&lt; (fs &lt;*&gt; xs)
&lt;/pre&gt;

&lt;p&gt;Or something like that :)&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Or, whenever this gets finished&#8230;</p>

<pre>
data Nat = Z | S Nat -- automatically lifted to the type/kind level!

data Vec :: Nat -&gt; * -&gt; * where
  ZVec :: Vec Z a
  (:&lt;) :: a -&gt; Vec n a -&gt; Vec (S n) a

class Pure n where pureN :: a -&gt; Vec n a

instance Pure Z where pureN a = ZVec
instance Pure (S n) where pureN a = a :&lt; pureN a

instance Applicative (Vec n) where
  pure a = pureN a
  ZVec &lt;*&gt; ZVec = ZVec
  (f :&lt; fs) &lt;*&gt; (x :&lt; xs) = f x :&lt; (fs &lt;*&gt; xs)
</pre>

<p>Or something like that <img src="http://conal.net/blog/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mikael Bung</title>
		<link>http://conal.net/blog/posts/doing-more-with-length-typed-vectors#comment-802</link>
		<dc:creator><![CDATA[Mikael Bung]]></dc:creator>
		<pubDate>Mon, 31 Jan 2011 13:16:47 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=293#comment-802</guid>
		<description><![CDATA[&lt;p&gt;Some time ago I tried to find a solution that didn&#039;t require an extra restriction on the context. As far as I can tell the IsNat solution is the best (in the sense that you only need to carry around one context) you can do currently but Maximes solution together with http://hackage.haskell.org/trac/ghc/wiki/KindSystem looks like it would allow the compiler to convince itself that the Applicative instance exists for all possible Vec n.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Some time ago I tried to find a solution that didn&#8217;t require an extra restriction on the context. As far as I can tell the IsNat solution is the best (in the sense that you only need to carry around one context) you can do currently but Maximes solution together with <a href="http://hackage.haskell.org/trac/ghc/wiki/KindSystem" rel="nofollow">http://hackage.haskell.org/trac/ghc/wiki/KindSystem</a> looks like it would allow the compiler to convince itself that the Applicative instance exists for all possible Vec n.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/doing-more-with-length-typed-vectors#comment-801</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Mon, 31 Jan 2011 01:25:06 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=293#comment-801</guid>
		<description><![CDATA[&lt;p
&gt;&lt;a href=&quot;http://conal.net/blog/posts/fixing-lists/comment-page-1/#comment-71660&quot;
  &gt;Maxime Henrion suggested&lt;/a
  &gt; an alternative to my &lt;code
  &gt;Applicative&lt;/code
  &gt; instance above:&lt;/p
&gt;

&lt;pre class=&quot;sourceCode haskell&quot;
&gt;&lt;code
  &gt;&lt;span class=&quot;kw&quot;
    &gt;instance&lt;/span
    &gt; &lt;span class=&quot;dt&quot;
    &gt;Applicative&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; &lt;span class=&quot;dt&quot;
    &gt;Z&lt;/span
    &gt;) &lt;span class=&quot;kw&quot;
    &gt;where&lt;/span
    &gt;&lt;br
     /&gt;  pure _ &lt;span class=&quot;fu&quot;
    &gt;=&lt;/span
    &gt; &lt;span class=&quot;dt&quot;
    &gt;ZVec&lt;/span
    &gt;&lt;br
     /&gt;  &lt;span class=&quot;dt&quot;
    &gt;ZVec&lt;/span
    &gt; &#8859; &lt;span class=&quot;dt&quot;
    &gt;ZVec&lt;/span
    &gt; &lt;span class=&quot;fu&quot;
    &gt;=&lt;/span
    &gt; &lt;span class=&quot;dt&quot;
    &gt;ZVec&lt;/span
    &gt;&lt;br
     /&gt;&lt;br
     /&gt;&lt;span class=&quot;kw&quot;
    &gt;instance&lt;/span
    &gt; &lt;span class=&quot;dt&quot;
    &gt;Applicative&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; n) &#8658; &lt;span class=&quot;dt&quot;
    &gt;Applicative&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;S&lt;/span
    &gt; n)) &lt;span class=&quot;kw&quot;
    &gt;where&lt;/span
    &gt;&lt;br
     /&gt;  pure a &lt;span class=&quot;fu&quot;
    &gt;=&lt;/span
    &gt; a &lt;span class=&quot;fu&quot;
    &gt;:&lt;&lt;/span
    &gt; pure a&lt;br
     /&gt;  (f &lt;span class=&quot;fu&quot;
    &gt;:&lt;&lt;/span
    &gt; fs) &#8859; (a &lt;span class=&quot;fu&quot;
    &gt;:&lt;&lt;/span
    &gt; as) &lt;span class=&quot;fu&quot;
    &gt;=&lt;/span
    &gt; f a &lt;span class=&quot;fu&quot;
    &gt;:&lt;&lt;/span
    &gt; (fs &#8859; as)&lt;br
     /&gt;&lt;/code
  &gt;&lt;/pre
&gt;

&lt;p
&gt;I hadn’t considered splitting the one instance into two. I like the simplicity of this solution, though I suspect the constraint &lt;code
  &gt;Applicative (Vec n)&lt;/code
  &gt; would be cumbersome in practice. A small drawback of this version is that it requires the GHC language extensions &lt;code
  &gt;FlexibleInstances&lt;/code
  &gt; and &lt;code
  &gt;FlexibleContexts&lt;/code
  &gt;.&lt;/p
&gt;

&lt;p
&gt;Continuing on to &lt;code
  &gt;Monad&lt;/code
  &gt;:&lt;/p
&gt;

&lt;pre class=&quot;sourceCode haskell&quot;
&gt;&lt;code
  &gt;&lt;span class=&quot;kw&quot;
    &gt;instance&lt;/span
    &gt; &lt;span class=&quot;kw&quot;
    &gt;Monad&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; &lt;span class=&quot;dt&quot;
    &gt;Z&lt;/span
    &gt;) &lt;span class=&quot;kw&quot;
    &gt;where&lt;/span
    &gt;&lt;br
     /&gt;  &lt;span class=&quot;fu&quot;
    &gt;return&lt;/span
    &gt;  &lt;span class=&quot;fu&quot;
    &gt;=&lt;/span
    &gt; pure&lt;br
     /&gt;  v &lt;span class=&quot;fu&quot;
    &gt;&gt;&gt;=&lt;/span
    &gt; f &lt;span class=&quot;fu&quot;
    &gt;=&lt;/span
    &gt; joinZ (&lt;span class=&quot;fu&quot;
    &gt;fmap&lt;/span
    &gt; f v)&lt;br
     /&gt;&lt;br
     /&gt;&lt;span class=&quot;kw&quot;
    &gt;instance&lt;/span
    &gt; &lt;span class=&quot;kw&quot;
    &gt;Monad&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; n) &#8658; &lt;span class=&quot;kw&quot;
    &gt;Monad&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;S&lt;/span
    &gt; n)) &lt;span class=&quot;kw&quot;
    &gt;where&lt;/span
    &gt;&lt;br
     /&gt;  &lt;span class=&quot;fu&quot;
    &gt;return&lt;/span
    &gt;  &lt;span class=&quot;fu&quot;
    &gt;=&lt;/span
    &gt; pure&lt;br
     /&gt;  v &lt;span class=&quot;fu&quot;
    &gt;&gt;&gt;=&lt;/span
    &gt; f &lt;span class=&quot;fu&quot;
    &gt;=&lt;/span
    &gt; joinS (&lt;span class=&quot;fu&quot;
    &gt;fmap&lt;/span
    &gt; f v)&lt;br
     /&gt;&lt;/code
  &gt;&lt;/pre
&gt;

&lt;pre class=&quot;sourceCode haskell&quot;
&gt;&lt;code
  &gt;joinZ &lt;span class=&quot;dv&quot;
    &gt;&#8759;&lt;/span
    &gt; &lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; &lt;span class=&quot;dt&quot;
    &gt;Z&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; &lt;span class=&quot;dt&quot;
    &gt;Z&lt;/span
    &gt; a) &#8594; &lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; &lt;span class=&quot;dt&quot;
    &gt;Z&lt;/span
    &gt; a&lt;br
     /&gt;joinZ &lt;span class=&quot;dt&quot;
    &gt;ZVec&lt;/span
    &gt; &lt;span class=&quot;fu&quot;
    &gt;=&lt;/span
    &gt; &lt;span class=&quot;dt&quot;
    &gt;ZVec&lt;/span
    &gt;&lt;br
     /&gt;&lt;br
     /&gt;joinS &lt;span class=&quot;dv&quot;
    &gt;&#8759;&lt;/span
    &gt; &lt;span class=&quot;kw&quot;
    &gt;Monad&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; n) &#8658; &lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;S&lt;/span
    &gt; n) (&lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;S&lt;/span
    &gt; n) a) &#8594; &lt;span class=&quot;dt&quot;
    &gt;Vec&lt;/span
    &gt; (&lt;span class=&quot;dt&quot;
    &gt;S&lt;/span
    &gt; n) a&lt;br
     /&gt;joinS (v &lt;span class=&quot;fu&quot;
    &gt;:&lt;&lt;/span
    &gt; vs) &lt;span class=&quot;fu&quot;
    &gt;=&lt;/span
    &gt; headV v &lt;span class=&quot;fu&quot;
    &gt;:&lt;&lt;/span
    &gt; join (&lt;span class=&quot;fu&quot;
    &gt;fmap&lt;/span
    &gt; tailV vs)&lt;br
     /&gt;&lt;/code
  &gt;&lt;/pre
&gt;

&lt;p
&gt;In this case, I&#039;m using the general &lt;code
  &gt;join&lt;/code
  &gt; function on monads. The &lt;code
  &gt;Monad&lt;/code
  &gt; instances would be more elegant and perhaps more efficient if &lt;code
  &gt;join&lt;/code
  &gt; were a method on &lt;code
  &gt;Monad&lt;/code
  &gt; as has been proposed.&lt;/p
&gt;
]]></description>
		<content:encoded><![CDATA[<p><a href="http://conal.net/blog/posts/fixing-lists/comment-page-1/#comment-71660"
  >Maxime Henrion suggested</a> an alternative to my <code>Applicative</code> instance above:</p>

<pre class="sourceCode haskell"
><code><span class="kw"
    >instance</span> <span class="dt"
    >Applicative</span> (<span class="dt"
    >Vec</span> <span class="dt"
    >Z</span>) <span class="kw"
    >where</span><br />  pure _ <span class="fu"
    >=</span> <span class="dt"
    >ZVec</span><br />  <span class="dt"
    >ZVec</span> &#8859; <span class="dt"
    >ZVec</span> <span class="fu"
    >=</span> <span class="dt"
    >ZVec</span><br /><br /><span class="kw"
    >instance</span> <span class="dt"
    >Applicative</span> (<span class="dt"
    >Vec</span> n) &#8658; <span class="dt"
    >Applicative</span> (<span class="dt"
    >Vec</span> (<span class="dt"
    >S</span> n)) <span class="kw"
    >where</span><br />  pure a <span class="fu"
    >=</span> a <span class="fu"
    >:&lt;</span> pure a<br />  (f <span class="fu"
    >:&lt;</span> fs) &#8859; (a <span class="fu"
    >:&lt;</span> as) <span class="fu"
    >=</span> f a <span class="fu"
    >:&lt;</span> (fs &#8859; as)<br /></code></pre>

<p>I hadn’t considered splitting the one instance into two. I like the simplicity of this solution, though I suspect the constraint <code>Applicative (Vec n)</code> would be cumbersome in practice. A small drawback of this version is that it requires the GHC language extensions <code>FlexibleInstances</code> and <code>FlexibleContexts</code>.</p>

<p>Continuing on to <code>Monad</code>:</p>

<pre class="sourceCode haskell"
><code><span class="kw"
    >instance</span> <span class="kw"
    >Monad</span> (<span class="dt"
    >Vec</span> <span class="dt"
    >Z</span>) <span class="kw"
    >where</span><br />  <span class="fu"
    >return</span>  <span class="fu"
    >=</span> pure<br />  v <span class="fu"
    >&gt;&gt;=</span> f <span class="fu"
    >=</span> joinZ (<span class="fu"
    >fmap</span> f v)<br /><br /><span class="kw"
    >instance</span> <span class="kw"
    >Monad</span> (<span class="dt"
    >Vec</span> n) &#8658; <span class="kw"
    >Monad</span> (<span class="dt"
    >Vec</span> (<span class="dt"
    >S</span> n)) <span class="kw"
    >where</span><br />  <span class="fu"
    >return</span>  <span class="fu"
    >=</span> pure<br />  v <span class="fu"
    >&gt;&gt;=</span> f <span class="fu"
    >=</span> joinS (<span class="fu"
    >fmap</span> f v)<br /></code></pre>

<pre class="sourceCode haskell"
><code>joinZ <span class="dv"
    >&#8759;</span> <span class="dt"
    >Vec</span> <span class="dt"
    >Z</span> (<span class="dt"
    >Vec</span> <span class="dt"
    >Z</span> a) &#8594; <span class="dt"
    >Vec</span> <span class="dt"
    >Z</span> a<br />joinZ <span class="dt"
    >ZVec</span> <span class="fu"
    >=</span> <span class="dt"
    >ZVec</span><br /><br />joinS <span class="dv"
    >&#8759;</span> <span class="kw"
    >Monad</span> (<span class="dt"
    >Vec</span> n) &#8658; <span class="dt"
    >Vec</span> (<span class="dt"
    >S</span> n) (<span class="dt"
    >Vec</span> (<span class="dt"
    >S</span> n) a) &#8594; <span class="dt"
    >Vec</span> (<span class="dt"
    >S</span> n) a<br />joinS (v <span class="fu"
    >:&lt;</span> vs) <span class="fu"
    >=</span> headV v <span class="fu"
    >:&lt;</span> join (<span class="fu"
    >fmap</span> tailV vs)<br /></code></pre>

<p>In this case, I'm using the general <code>join</code> function on monads. The <code>Monad</code> instances would be more elegant and perhaps more efficient if <code>join</code> were a method on <code>Monad</code> as has been proposed.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
