<p dir="ltr">I've put up a pull request at <a href="https://github.com/haskell/deepseq/pull/18">https://github.com/haskell/deepseq/pull/18</a> adding rnfFoldableLTR and rnfFoldableRTL, and documenting when they can (and when they cannot) produce good NFData instances. The implementations are monoid based, but use slightly different monoid definitions than originally proposed so as to produce extremely clean Core for GHC >= 7.8 even without specialization. Edward: similar functions could also be written for Bifoldable. I'd be happy to send a PR to bifunctors if you'd like.</p>
<div class="gmail_extra"><br><div class="gmail_quote">On Jul 14, 2016 3:09 PM, "Edward Kmett" <<a href="mailto:ekmett@gmail.com">ekmett@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">The monoid may be more efficient if the Foldable is constructed to take advantage of internal sharing.<div><br></div><div>-Edward</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jul 14, 2016 at 11:52 AM, David Feuer <span dir="ltr"><<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><p dir="ltr">I guess these are equivalent to the simpler expressions</p>
<p dir="ltr">rnfLTR = foldl' (const rnf) ()<br>
rnfRTL = foldr' (\x _ -> rnf x) ()</p><div><div>
<div class="gmail_extra"><br><div class="gmail_quote">On Jul 13, 2016 11:16 PM, "David Feuer" <<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">As I describe in <a href="https://github.com/haskell/deepseq/issues/17" rel="noreferrer" target="_blank">https://github.com/haskell/deepseq/issues/17</a> it is<br>
possible to implement an NFData instance for any Foldable type, and we<br>
can offer a function to help do that:<br>
<br>
data Unit = Unit<br>
<br>
instance Monoid Unit where<br>
  mempty = Unit<br>
  Unit `mappend` Unit = Unit -- strict in both arguments, unlike ()<br>
<br>
rnfFoldable :: (Foldable f, NFData a) => f a -> ()<br>
rnfFoldable xs = foldMap (\x -> rnf x `seq` Unit) xs `seq` ()<br>
<br>
This could be used like so:<br>
<br>
instance NFData a => NFData (F a) where<br>
  rnf = rnfFoldable<br>
<br>
This version forces from left to right. It would be possible to offer<br>
another version that forces from right to left:<br>
<br>
data Unit2 = Unit2<br>
<br>
instance Monoid Unit2 where<br>
  mempty = Unit2<br>
  x `mappend` Unit2 = x `seq` Unit2<br>
<br>
rnfFoldableRTL :: (Foldable f, NFData a) => f a -> ()<br>
rnfFoldableRTL xs = foldMap (\x -> rnf x `seq` Unit2) xs `seq` ()<br>
</blockquote></div></div>
</div></div><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>
<br></blockquote></div><br></div>
</blockquote></div></div>