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@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@haskell.org
http://www.haskell.org/mailman/listinfo/libraries




_______________________________________________
Libraries mailing list
Libraries@haskell.org
http://www.haskell.org/mailman/listinfo/libraries