<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>