<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body bgcolor="#FFFFFF" text="#000000">
The <a href="https://github.com/NICTA/course">NICTA course</a>
includes exercises on the type class Extend, in Course/Extend.hs.
Extend is a superclass of Comonad. Here's the class definition:<br>
<blockquote type="cite"><tt>-- | All instances of the `Extend`
type-class must satisfy one law. This law</tt><tt><br>
</tt><tt>-- is not checked by the compiler. This law is given as:</tt><tt><br>
</tt><tt>--</tt><tt><br>
</tt><tt>-- * The law of associativity</tt><tt><br>
</tt><tt>-- `∀f g. (f <<=) . (g <<=) ≅ (<<=)
(f . (g <<=))`</tt><tt><br>
</tt><tt>class Functor f => Extend f where</tt><tt><br>
</tt><tt> -- Pronounced, extend.</tt><tt><br>
</tt><tt> (<<=) ::</tt><tt><br>
</tt><tt> (f a -> b)</tt><tt><br>
</tt><tt> -> f a</tt><tt><br>
</tt><tt> -> f b</tt><tt><br>
</tt><tt><br>
</tt><tt>infixr 1 <<=</tt><tt><br>
</tt></blockquote>
<br>
Could someone please motivate the Extend instance for List? (Its
implementation is left as an exercise. In the course, type List a is
isomorphic to [a].) Some of the tests (<<=) is expected to
pass are shown, and make clear what ought to happen.<br>
<blockquote type="cite"><tt>-- | Implement the @Extend@ instance for
@List@.</tt><tt><br>
</tt><tt>--</tt><tt><br>
</tt><tt>-- >>> length <<= ('a' :. 'b' :. 'c' :.
Nil)</tt><tt><br>
</tt><tt>-- [3,2,1]</tt><tt><br>
</tt><tt>--</tt><tt><br>
</tt><tt>-- >>> id <<= (1 :. 2 :. 3 :. 4 :. Nil)</tt><tt><br>
</tt><tt>-- [[1,2,3,4],[2,3,4],[3,4],[4]]</tt><tt><br>
</tt><tt>--</tt><tt><br>
</tt><tt>-- >>> reverse <<= ((1 :. 2 :. 3 :. Nil)
:. (4 :. 5 :. 6 :. Nil) :. Nil)</tt><tt><br>
</tt><tt>-- [[[4,5,6],[1,2,3]],[[4,5,6]]]</tt><tt><br>
</tt></blockquote>
<br>
The following (wrong, according to the tests) Extend instance for
List nevertheless obeys the types and obeys the Extend law of
associativity.<br>
<blockquote type="cite"><tt>instance Extend List where</tt><tt><br>
</tt><tt> (<<=) ::</tt><tt><br>
</tt><tt> (List a -> b)</tt><tt><br>
</tt><tt> -> List a</tt><tt><br>
</tt><tt> -> List b</tt><tt><br>
</tt><tt> (<<=) f = (:. Nil) . f</tt><tt><br>
</tt></blockquote>
<tt>(:. Nil) is analogous to (: []), create a singleton list.</tt><br>
<br>
I can't find a good reference on the Extend type class to convince
me why the correct Extend instance for List in the course is the
desirable one. (I'm not saying my version is desirable, in fact it
seems fairly useless, but it works.)<br>
<br>
Graham<br>
<br>
</body>
</html>