14
import Prelude hiding (foldr)

import Control.Applicative
import Data.Foldable
import Data.Traversable

left, right :: (Applicative f, Traversable t) => (a -> b -> b) -> b -> t (f a) -> f b
left f z = fmap (foldr f z) . sequenceA
right f z = foldr (liftA2 f) (pure z)

I have a strong suspicion that the expressions left and right are equal, but how to prove it?

Sjoerd Visscher
  • 11,840
  • 2
  • 47
  • 59

1 Answers1

9

Here's a start at least:

\f z -> fmap (foldr f z) . sequenceA
== (definition of Foldable foldr)
\f z -> fmap (foldr f z . toList) . sequenceA
== (distributivity of fmap)
\f z -> fmap (foldr f z) . fmap toList . sequenceA
== (need to prove this step, but it seems intuitive to me)
\f z -> fmap (foldr f z) . sequenceA . toList

\f z -> foldr (liftA2 f) (pure z)
== (definition of Foldable foldr)
\f z -> foldr (liftA2 f) (pure z) . toList

If you can prove that fmap toList . sequenceA = sequenceA . toList, and that your original claim holds for t = [] you should be good to go.

hammar
  • 138,522
  • 17
  • 304
  • 385
  • 1
    `fmap toList . sequenceA = sequenceA . toList` holds, see http://patternsinfp.wordpress.com/2011/05/17/distributivity-in-horners-rule/, the post that lead me to this question. But I'd like to be able to prove this without going through lists. – Sjoerd Visscher May 19 '11 at 12:27
  • 3
    Actually, thinking a bit more about it, going through lists makes a lot of sense when using foldr. Thanks! – Sjoerd Visscher May 19 '11 at 12:53