<div dir="ltr">As a less-capable Haskeller, I agree 100%.<div><br></div><div>The whole point of importing Data.List (either directly or from the Prelude) is to get functions that work on lists. A crucial feature of this is that applying these functions to non-lists should generate type errors, so that I can notice that I passed e.g. a tuple where I meant to pass a list. I would be fine with adding Foldable versions of list functions to Data.Foldable: if I want my functions to work on arbitrary Foldables, that's what I would import.<div><br></div><div>As someone who spends some time teaching beginners Haskell, this is a disaster. Trying to explain to a beginner why "Data.List.length ('x', 'y')" returns a number instead of failing is bad enough: trying to explain why it returns 1 is hopeless. (I'm better off with Python: at least there it has the grace to return 2.) And then I have to explain why "length ('x', 'y', 'z')" returns an utterly incomprehensible type error? No thanks.</div></div><div><br></div><div>I'm recommending SML over Haskell to beginners a lot more these days.</div><br><div class="gmail_quote"><div dir="ltr">On Wed, Feb 17, 2016 at 3:02 AM Henning Thielemann <<a href="mailto:lemming@henning-thielemann.de" target="_blank">lemming@henning-thielemann.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
On Mon, 18 Jan 2016, Ryan Scott wrote:<br>
<br>
> * The Not-A-Wat in Haskell:<br>
> <a href="https://www.youtube.com/watch?v=87re_yIQMDw" rel="noreferrer" target="_blank">https://www.youtube.com/watch?v=87re_yIQMDw</a><br>
<br>
I see his examples and draw the opposite conclusions. What he presents are<br>
perfect Wats and they have eventually moved Haskell to the MatLab league<br>
where everything is allowed and the programming system accepts almost<br>
everything the programmer enters.<br>
<br>
Sure,<br>
<br>
> length (2,3) = 1<br>
> product (2,3) = 3<br>
> sum (2,3) = 3<br>
> or (True,False) = False<br>
<br>
are all consistent but consistently useless, unintuitive (not only to<br>
novices) and dangerous. There are alternatives: There was no need to<br>
generalize 'Prelude.length' using Foldable. I always opposed to the<br>
argument "put the most general variant to Prelude", because there is no<br>
clear most general variant or there is one like "length :: Length f => f"<br>
and you won't like it.<br>
<br>
We could reasonably have the Haskell 98 class<br>
<br>
   class Length a where<br>
      length :: a -> Int<br>
<br>
   instance Length [a] where<br>
      length = List.length<br>
<br>
   instance Length (a,b) where<br>
      length _ = 2<br>
<br>
This would yield the intuitive<br>
   length (2,3) = 2<br>
<br>
I do not propose to implement this class, because I never encountered a<br>
situation where I could equally choose between lists and pairs. If at all,<br>
I can see value in a special TupleSize class. However, the Length class<br>
proves that the suggestion that the only reasonable result of 'length<br>
(2,3)' is 1, is plain wrong.<br>
<br>
How did we get there? There were three steps that made this Wat possible:<br>
   1. Foldable.length added<br>
   2. instance Foldable ((,) a)<br>
   3. export Foldable.length from Prelude.<br>
<br>
For me<br>
   1. was correct<br>
   2. was wrong because a programmer should better define a custom type<br>
      like "data AdornedSingleton a b = AS a b"<br>
   3. Was wrong because there are multiple ways to generalize 'length'.<br>
      Without 3. you would have to use explicitly 'length' from Foldable<br>
      and this way you would have been warned, that strange things may happen.<br>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div></div>