suggestion: use lazy pattern matching for Monoid instances of tuples

Gabriel Gonzalez gabriel439 at gmail.com
Sun Aug 18 23:21:49 CEST 2013


I'm guessing this proposal is related to this Stack Overflow answer you 
gave:

http://stackoverflow.com/a/18289075/1026598

Note that your solution is very similar to the solution in the `foldl` 
package I just released (also based off of the same blog post you got 
your solution from).  The key differences are that:

* The `foldl` solution is for left folds and uses a strict tuple 
internally to prevent space leaks
* Your solution is for right folds and uses an extra-lazy tuple 
internally to promote laziness

This suggests to me that it would be better to keep this extra-lazy 
tuple as an internal implementation detail of a right-fold package that 
would be the lazy analogy of `foldl`, rather than modifying the standard 
Haskell tuple.

On 08/18/2013 01:44 PM, Edward Kmett wrote:
> This change would spontaneously introduce space-leaks in currently 
> non-leaky code.
>
> It'd be a debugging nightmare for existing users of the product Monoid 
> instance, of whom there are many, who would just see their code start 
> to throw away all their memory on newer GHC versions and have little 
> or no idea why, if they missed news of this update.
>
> As a result I'm -1 on this proposal.
>
> That said, some kind of package that provides a well-reasoned 
> Data.Tuple.Lazy data type could see use, as using it would imply 
> consent to those semantics.
>
> I do not object morally to it, like Henning, merely pragmatically.
>
> -Edward
>
>
>
> On Sat, Aug 17, 2013 at 4:31 PM, Petr Pudlák <petr.mvd at gmail.com 
> <mailto:petr.mvd at gmail.com>> wrote:
>
>     Dear haskellers,
>
>     currently the instances are defined as
>
>     |instance  (Monoid  a,Monoid  b) =>Monoid  (a,b)where
>              mempty = (mempty, mempty)
>              (a1,b1) `mappend` (a2,b2) = (a1 `mappend` a2, b1 `mappend` b2)|
>
>     However for some applications this isn't lazy enough, for example
>
>     |-- | Build two lists by folding on a pair of `Endo` monoids.
>     test  = head $ appEndo (fst $ foldMap (f &&& f) [1..]) []
>        where
>          f =Endo  . (:)|
>
>     never terminates because of the unnecessary pattern matching on
>     the constructor |(,)| forces evaluation of the whole infinite list.
>
>     I suggest to change all Monoid instances for tuples to be like
>
>     |  instance  (Monoid  a,Monoid  b) =>Monoid  (a,b)where
>               mempty = (mempty, mempty)
>               ~(a1,b1) `mappend` ~(a2,b2) = (a1 `mappend` a2, b1 `mappend` b2)
>     --      ^^^                ^^^|
>
>     which fixes the problem.
>
>     Best regards,
>     Petr
>
>
>     _______________________________________________
>     Libraries mailing list
>     Libraries at haskell.org <mailto:Libraries at haskell.org>
>     http://www.haskell.org/mailman/listinfo/libraries
>
>
>
>
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://www.haskell.org/mailman/listinfo/libraries

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/libraries/attachments/20130818/b48eaf23/attachment.htm>


More information about the Libraries mailing list