Even this is problematic. Simplifying a bit, I managed to do this recently: module A (foo) where foo :: Bar -> [Int] foo = ... some hacky explicit recursion ... module B where import A bar :: Bar -> Int bar = ... expression containing 'sum . foo' ... Then I noticed I had some calls to 'maximum' on the result of 'foo', and wanted to just modify 'foo' to return the maximum value directly, along with the list: foo :: Bar -> ([Int], Int) foo = ... I went through and replaced the calls to 'maximum' with 'snd', but forgot about 'sum'. GHC happily compiled my code, but was now returning the maximum value instead of the sum of the values. This, of course, caused some other bit to behave strangely, and took some calls to 'trace' to figure out what was going on. There are lots of ways to avoid this... richer return type, use Data.OldList, write some tests, more conscientious search and replace refactoring... but the ease of refactoring code is one of the things I love about Haskell. Normally, I can just change a type signature and hit :r in ghci and start fixing type errors, confident that I've covered my bases when it eventually compiles. Now I feel like I can't rely on the typechecker as much. And yes, explaining the difference between maximum (2,1) and maximum [2,1] to a beginner is a pain, and really weakens your claim that the type system will prevent a lot of bugs in your code (at least in the beginner's eyes). I don't know what the solution is... the instances are already there and a lot of code relies on them, but I do feel like they fall on the wrong side of the expressivity/safety line. On Wed, Feb 24, 2016 at 1:04 AM, Simon Peyton Jones <simonpj@microsoft.com> wrote:
| So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function.
I strongly agree, for all the reasons Andreas mentions. GHC's source code has *lots* of data types that are isomorphic to tuples. Crucial!
Simon
| -----Original Message----- | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of | Andreas Abel | Sent: 24 February 2016 08:58 | To: Nathan Bouscal <nbouscal@gmail.com>; libraries@haskell.org | Subject: Re: Haskell Foldable Wats | | In my n+1 years of participating in a 100kloc Haskell project, I | learned that programming with the "categorical" data type building | blocks "Either" and tuples leads to code that is hard to read and | maintain. It is tempting to use a pair | | type QNamed a = (QName, a) | | instead of a hand-rolled data type | | data QNamed a = QNamed { qname :: QName, qnamedThing :: a } | | since with pairs, I get lots of operations for free, and even more if I | use Functor and Traversable, it seems. However, in the long run, if I | come back after months to my original code, or even worse, to someone | else's code, I dearly pay for this: | | 1. Harder to read the code, as I may only see the non-telling "fst" | and "snd" instead of the semantics-loaden "qname" and "qnamedThing". | | 2. Lack of code exploration facilities like grep and tags. I can | grep for "QName" and "qname", but grepping for "," and "fst" returns | lots of irrelevant locations. | | 3. Non-telling error messages. | | And all the arguments of using newtypes over type synonyms apply here | as well. | | So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function. I am speaking here of | Haskell as a language for software development, not of Haskell as a | realization of category theory. | | For getting a broader acceptance of Haskell as a language for software | development, Foldable on tuples is not helpful. | | And yes, if I was new to Haskell and learned the GHCI thinks that | | minimum (1,2) == 1 | | then I would advice GHCI to visit some mental institution to get its | delusions fixed. | | --Andreas | | | On 23.02.2016 18:29, Nathan Bouscal wrote: | > Sorry, poor quoting on my part. I was attempting to reply to | Andreas's | > earlier points: | > | > >> Use of tuples is highly discourageable… | >>>I see no point in Functor or Foldable for tuples. | > | > On Tue, Feb 23, 2016 at 5:18 PM, Mario Blažević <mblazevic@stilo.com | > <mailto:mblazevic@stilo.com>> wrote: | > | > On 16-02-23 11:23 AM, Nathan Bouscal wrote: | > | > It's a bit bold to simultaneously say "Nobody should use this | > type," and | > also "If you use this type, you should do it this way." If | you think | > that it's bad practice to use tuples, that's a fine and | respectable | > opinion, but at that point you should start being a bit more | > wary about | > telling those who think otherwise /how/ they should use them. | > | > | > I believe he was referring to lists, not to tuples. | There | > were few Prelude functions limited to tuples before FTP, and | those | > haven't changed. | > | > | > | > On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek | > <marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com> | > <mailto:marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com>>> wrote: | > | > > I can assure you that Andreas is not delusional | > | > I didn't say that. I was referring to his response to my | > post, that | > "Some delusions have very sophisticated explanations." | > | > > You have to show good taste or you'll end up with a | mess | > that might be logically consistent, but unpleasant to use. | > | > This is entirely subjective, and frankly I don't think | that | > post-FTP | > Haskell is a "mess" or is "unpleasant to use". If | anything, | > it became | > more useful to me, because now Prelude functions aren't | > limited to the | > one data structure I almost never use. | > | > Best regards, | > Marcin Mrotek | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org <mailto:Libraries@haskell.org> | > | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | | | -- | Andreas Abel <>< Du bist der geliebte Mensch. | | Department of Computer Science and Engineering Chalmers and Gothenburg | University, Sweden | | andreas.abel@gu.se | https://na01.safelinks.protection.outlook.com/?url=http:%2f%2fwww2.tcs. | ifi.lmu.de%2f~abel%2f&data=01%7C01%7Csimonpj%40064d.mgd.microsoft.com%7 | Ce4033ee9a03a42eaa97108d33cf89187%7C72f988bf86f141af91ab2d7cd011db47%7C | 1&sdata=kvwlaXofxhQV2ZCD9K%2bemtG4S9oCujNYhn1IXTnSZtc%3d | _______________________________________________ | Libraries mailing list | Libraries@haskell.org | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.ha | skell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries%0a&data=01%7c01%7csimonpj%40064d.m | gd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c72f988bf86f141af9 | 1ab2d7cd011db47%7c1&sdata=gMTA2SOTm1seAHbvHPWnsDjAa7y1gAS681kW6YUx1mQ%3 | d _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries