<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 22, 2017 at 4:12 AM, Sven Panne <span dir="ltr"><<a href="mailto:svenpanne@gmail.com" target="_blank">svenpanne@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2017-03-21 22:29 GMT+01:00 Edward Kmett <span dir="ltr"><<a href="mailto:ekmett@gmail.com" target="_blank">ekmett@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>[... In general I think the current behavior is the least surprising as it "walks all the a's it can" and is the only definition compatible with further extension with Traversable. [...]</div></div></blockquote><div><br></div><div>OTOH, the current behavior contradicts my intuition that wrapping a type into data/newtype plus using the deriving machinery is basically a no-op (modulo bottoms etc.). When I e.g. wrap a type t, I would be very surprised if the Eq/Ord instances of the wrapped type would behave differently than the one on t. I know that this is very handwavy argument, but I think the current behavior is *very* surprising.</div><div><br></div><div>Somehow the current behavior seems to be incompatible with the FTP, where pairs are given a special treatment (if that't the right/intuitive choice is a completely different topic, though).</div></div></div></div></blockquote><div><br></div><div>I'm not sure what you mean by "pairs are given a special treatment".  Tuples are given the only possible treatment:</div><div><br></div><div>data (,) a b = (a,b)</div><div><br></div><div>The b is the only place to fold over with a Foldable or change with a Functor instance.  When things are monomorphic there are more options and that leads to the least surprising, fold over all the options for:</div><div><br></div><div>data Pair a = Pair a a</div><div><br></div><div>or</div><div><br></div><div>data X a = X (a,a)</div><div><br></div><div>The (a,a) here is most certainly not the same thing as (a,b).  There is something that is a bit surprising to me in that DerivingFoldable will not a user declared data type for pair with two arguments:</div><div><br></div><div><div>> data Pair a = Pair a a deriving (Functor, Foldable, Show)</div><div>> data X a = X (Pair a) deriving (Functor, Foldable, Show)<br></div><div>> length (X (Pair 1 2))</div><div>2</div><div>> data Tup a b  = Tup a b deriving (Functor, Foldable, Show)</div><div>> data Y a = Y (Tup a a) deriving (Functor, Show)<br></div><div><br></div><div><interactive>:10:34: error:</div><div>    • Can't make a derived instance of ‘Functor Y’:</div><div>        Constructor ‘Y’ must use the type variable only as the last argument of a data type</div><div>    • In the data declaration for ‘Y’</div><div>> data Y a = Y (Tup a a) deriving (Foldable, Show)</div><div><br></div><div><interactive>:11:34: error:</div><div>    • Can't make a derived instance of ‘Foldable Y’:</div><div>        Constructor ‘Y’ must use the type variable only as the last argument of a data type</div><div>    • In the data declaration for ‘Y’</div><div>> data Y a = Y (Tup a a) deriving (Foldable, Show)</div></div><div><br></div><div>But it is happy to do just that with (a,a).</div><div><br></div><div><br></div><div>Ryan</div><div><br></div></div></div></div>