<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Jan 27, 2015 at 5:32 AM, Augustsson, Lennart <span dir="ltr"><<a href="mailto:Lennart.Augustsson@sc.com" target="_blank">Lennart.Augustsson@sc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">





<div lang="EN-GB" link="blue" vlink="purple">
<div>
<p class="MsoNormal">The next version (7.10) of GHC is slated to have a drastically changed Prelude.<u></u><u></u></p>
<p class="MsoNormal">This message is very late in the release process, but I would urge caution before changing.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The changes are (aptly) named the Burning Bridges Proposal (BBP).<u></u><u></u></p>
<p class="MsoNormal">Even though the work has been going on for a while, it seems that this<u></u><u></u></p>
<p class="MsoNormal">change is coming as a surprise to many people (including Simon Peyton<u></u><u></u></p>
<p class="MsoNormal">Jones).  In summary, it generalizes many list operation, e.g., foldr,<u></u><u></u></p>
<p class="MsoNormal">to be overloaded.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">There is much to welcome in BBP, but changing the Prelude cannot be<u></u><u></u></p>
<p class="MsoNormal">done lightly since it really is like changing the language.<u></u><u></u></p>
<p class="MsoNormal">So I think it's really important for a large number of people to be able to<u></u><u></u></p>
<p class="MsoNormal">try out such changes before they come into effect, and to have time<u></u><u></u></p>
<p class="MsoNormal">to let the changes stabilize (you rarely get it right the first time).<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I've discussed this with a number of people, including Simon PJ, and<u></u><u></u></p>
<p class="MsoNormal">we have concrete proposals.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Proposal 1:<u></u><u></u></p>
<p class="MsoNormal">*    Add a new pragma<u></u><u></u></p>
<p class="MsoNormal">        {-# LANGUAGE Prelude=AlternativePrelude #-}<u></u><u></u></p>
<p class="MsoNormal">      *   This is a new feature, but it is easy and low-risk to implement.<u></u><u></u></p>
<p class="MsoNormal">      *   Which Prelude you use really is a language choice; appropriate for a LANGUAGE pragma.<u></u><u></u></p>
<p class="MsoNormal">      *   Semantics is name-space only: import Prelude (); import AlternativePrelude<u></u><u></u></p>
<p class="MsoNormal">      *   No effect on desugaring or typing of built-in syntax (list comprehensions, do-notation etc).</p></div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-GB" link="blue" vlink="purple"><div><p class="MsoNormal">*    Ship with both old and new prelude. </p></div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-GB" link="blue" vlink="purple"><div><p class="MsoNormal">*    So now old and new behaviour are easy to achieve, in the module or in a .cabal file.<u></u><u></u></p>
<p class="MsoNormal"></p></div></div></blockquote><div><br></div><div><br></div><div><div>This actually <b>doesn't work</b>. We seriously considered it, but the effects have knock-on consequences that go far beyond the Prelude itself. </div><div><br></div><div>Control.Monad for instance re-exports `mapM`</div><div><br></div><div>Data.List re-exports most of the folds.</div><div><br></div><div>`mtl` re-exports the monad combinators as well, etc.</div><div><br></div><div>The list goes on and on.</div><div><br></div><div>We made a serious go at trying this proposal before we abandoned it as unworkable, because of the re-export issue.</div><div><br></div><div>import Data.List</div><div><br></div><div>would have to collide or not collide with Prelude types based on whether or not the Prelude was being used or this alternate Prelude.</div><div><br></div><div>import Control.Monad</div><div>import Data.Foldable<br></div><div>import Data.Traversable<br></div><div><br></div><div>etc.</div><div><br></div><div>the list goes on.</div><div><br></div><div>Under the scheme we've adopted all of these work unconditionally.</div><div><br></div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-GB" link="blue" vlink="purple"><div><p class="MsoNormal">Q1<u></u><u></u></p>
<p class="MsoNormal">An alternative to Foldable would be <u></u><u></u></p>
<p class="MsoNormal">  class Enumerable t where<u></u><u></u></p>
<p class="MsoNormal">    toList :: t a -> [a]   -- Implementations should use 'build'<u></u><u></u></p>
<p class="MsoNormal">Is Foldable more general (or efficient) than a Enumerable class, plus fusion? 
<u></u><u></u></p>
<p class="MsoNormal"><u></u></p></div></div></blockquote><div><br></div><div>This is insufficient in a lazy language, it forces all folds to be left-biased, and introduces bottoms that do not exist in a foldMap based Foldable.</div><div><br></div><div>class Foldable f where</div><div>  foldMap :: Monoid m => (a -> m) -> f a -> m</div><div><br></div><div>on the other hand would be a very serious candidate for a minimalist Foldable, but then we run afoul of Q2.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-GB" link="blue" vlink="purple"><p class="MsoNormal"><u></u></p>
<p class="MsoNormal">Consider a new data type X a.  I write<u></u><u></u></p>
<p class="MsoNormal">     foldX :: (a -> b -> b) -> b -> X a -> b<u></u><u></u></p>
<p class="MsoNormal">     foldX = ...lots of code...<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">     toList :: X a -> [a]  {-# INLINE toList #-}<u></u><u></u></p>
<p class="MsoNormal">     toList x = build (\c n. foldX c n x)<u></u><u></u></p>
<p class="MsoNormal">            <u></u><u></u></p>
<p class="MsoNormal">So now toList is small and easy to inline.  Every good list consumer of a call to toList will turn into a call to foldX, which is what we want.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Q2<u></u><u></u></p>
<p class="MsoNormal">What are the criteria for being in Foldable?<u></u><u></u></p>
<p class="MsoNormal">For instance, why are 'sum', 'product' in Foldable, but not 'and', 'or'?<u></u><u></u></p>
<p class="MsoNormal"><u></u></p></div></blockquote><div><br></div><div>sum and product went into Foldable because Prelude.sum and Data.Foldable.sum folded in opposite directions. </div><div><br></div><div>and/or didn't have this problem.</div><div><br></div><div>For any new data type, defining foldMap alone is sufficient. </div><div><br></div><div>For [] on the other hand we decided that expanding Foldable to avoid silently changing the semantics of all Haskell programs ever written was the lesser of two evils.</div><div><br></div><div><div>It was considered _by far_ the lesser of evils to expand the class to enable it to duplicate existing semantics where possible rather than silently change the semantics of which way folks code associated for all Haskell programs ever written.</div></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-GB" link="blue" vlink="purple">
<p class="MsoNormal">Q3<u></u><u></u></p>
<p class="MsoNormal">What's the relationship of Foldable to GHC.Exts.IsList?<u></u><u></u></p>
<p class="MsoNormal">Which also has toList, fromList, and does work with ByteString.<u></u><u></u></p>
<p class="MsoNormal">*  For example, could we use IsList instead of Foldable?<u></u><u></u></p>
<p class="MsoNormal">    Specifically, Foldable does not use its potential power to apply the type constructor t to different arguments.  (Unlike Traversable which does.)<u></u><u></u></p>
<p class="MsoNormal">        foldr :: IsList l => (Item l->b->b) -> b -> l -> b</p>
<p class="MsoNormal"><u></u></p></div></blockquote><div><br></div><div>Because IsList includes both fromList and toList, _and_ is over an argument of kind * not an argument of kind * -> *, IsList has no connection to Foldable.</div><div><br></div><div>At best what you can say is that the toList for Data.Foldable and the toList for IsList should yield the same answer if you want to be sensible, but remember IsList is on a different kind entirely, and there are usecases that require it to have that kind.</div><div><br></div><div>-Edward</div></div></div></div>