<p dir="ltr">It's not terribly unusual. Functor can be a superclass of Applicative because</p>
<p dir="ltr"> fmap f xs = pure f <*> xs</p>
<p dir="ltr">Applicative can be a superclass of Monad because</p>
<p dir="ltr"> pure = return<br>
(<*>) = ap</p>
<p dir="ltr">Distributive can be a superclass of Representable because</p>
<p dir="ltr">distribute wf = tabulate (\k -> fmap (`index` k) wf)</p>
<p dir="ltr">Obviously, it often *doesn't* work like this. The class structure may be arranged as it is because the subclass conceptually or practically represents a refinement of the superclass. But when the methods of a given class can be implemented using the methods of another, that suggests that it *might* make sense for it to be a superclass.</p>
<div class="gmail_quote">On Feb 6, 2016 10:10 AM, "David Banas" <<a href="mailto:capn.freako@gmail.com">capn.freako@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Hi David,<div><br></div><div>Thanks for your reply!</div><div><br></div><div>That’s really interesting; I never would have thought to try and implement super-class member functions, in terms of sub-class member functions.</div><div>I was trying to go the other way: implement sequenceA, in terms of foldMap, which seemed to require a completely generic way of turning an Applicative (guaranteed by the type signature of sequenceA) into a Monoid (required by foldMap). I came up with this:</div><div><br></div><div><div><br></div><div>{-# LANGUAGE Rank2Types</div><div> FlexibleContexts</div><div> UndecidableInstances</div><div> AllowAmbiguousTypes</div><div> #-}</div><div><br></div><div>newtype MonApp = MonApp {getApp :: (Applicative f, Monoid a) => f a}</div><div><br></div><div>instance Monoid MonApp where</div><div> mempty = MonApp $ pure mempty</div><div> mappend ma1 ma2 = MonApp $ mappend <$> (getApp ma1) <*> (getApp ma2)</div><div><br></div><div>instance (Monoid a) => Monoid (Tree a) where</div><div> mempty = Empty</div><div> mappend Empty t = t</div><div> mappend t Empty = t</div><div> mappend (Leaf x) (Leaf y) = Leaf (x `mappend` y)</div><div> mappend (Leaf x) (Node t1 y t2) = Node t1 (x `mappend` y) t2</div><div> mappend (Node t1 y t2) (Leaf x) = Node t1 (y `mappend` x) t2</div><div> mappend (Node t1 x t2) (Node t3 y t4) = Node (t1 `mappend` t3) (x `mappend` y) (t2 `mappend` t4)</div><div><br></div><div>instance Monoid (Tree a) => Traversable Tree where</div><div> sequenceA = getApp . foldMap (MonApp . (fmap Leaf))</div><div><br></div><div><br></div><div>to which the compiler responded:</div><div><br></div><div><br></div><div><span style="white-space:pre-wrap;background-color:rgb(255,255,255)">Couldn't match type ‘f (Tree a1)’ with ‘forall (f1 :: * -> *) a2. (Applicative f1, Monoid a2) => f1 a2’</span><span style="white-space:pre-wrap"><br style="white-space:pre-wrap"></span><span style="white-space:pre-wrap;background-color:rgb(255,255,255)">Expected type: f (Tree a1) -> interactive:IHaskell161.MonApp</span><span style="white-space:pre-wrap"><br style="white-space:pre-wrap"></span><span style="white-space:pre-wrap;background-color:rgb(255,255,255)"> Actual type: (forall (f :: * -> *) a. (Applicative f, Monoid a) => f a) -> interactive:IHaskell161.MonApp</span><span style="white-space:pre-wrap"><br style="white-space:pre-wrap"></span><span style="white-space:pre-wrap;background-color:rgb(255,255,255)">Relevant bindings include sequenceA :: Tree (f a1) -> f (Tree a1) (bound at </span><u></u>:14:3)<br>In the first argument of ‘(.)’, namely ‘IHaskell161.MonApp’<br>In the first argument of ‘foldMap’, namely ‘(interactive:IHaskell161.MonApp . (fmap Leaf))’<u></u></div><div><u></u><br><u></u></div><div><u></u><br><u></u></div><div><u></u>-db<u></u></div><div><u></u><br><u></u></div><div><span style="color:rgb(255,0,0);font-family:monospace;font-size:14px;font-style:italic;white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></div><div><div>On Feb 5, 2016, at 11:20 AM, David Feuer <<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>> wrote:</div><br><blockquote type="cite"><p dir="ltr">It's not so much that it's *necessary* as that it's *possible*. The existence of two functions in Data.Traversable explains both of the superclasses of Traversable:</p><p dir="ltr">fmapDefault :: Traversable t => (a -> b) -> t a -> t b</p><p dir="ltr">foldMapDefault :: (Traversable t, Monoid m) => (a -> m) -> t a -> m</p><p dir="ltr">Each of these is written using only traverse, and they can be used to define fmap and foldMap for types when you've written traverse.</p><p dir="ltr">Hint: Consider traversing using the following applicative functors:</p><p dir="ltr">newtype Const a b = Const a<br>
instance Monoid a => Applicative (Const a)</p><p dir="ltr">newtype Identity a = Identity a<br>
instance Applicative Identity</p>
<div class="gmail_quote">On Feb 5, 2016 1:45 PM, "David Banas" <<a href="mailto:capn.freako@gmail.com" target="_blank">capn.freako@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi all,<div><br></div><div>I don't understand why Foldable is a necessary super-class of Traversable, and I suspect that the Applicative/Monoid duality, which I've just begun discovering in the literature, has something to do with why that is so.</div><div><br></div><div>Can anyone give me a hint, without giving me the answer?</div><div><br></div><div>Thanks!</div><div>-db</div><div><br></div></div>
<br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div>
</blockquote></div><br></div></div></blockquote></div>