Search code examples
haskellproof

Is this always true: fmap (foldr f z) . sequenceA = foldr (liftA2 f) (pure z)


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?


Solution

  • 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.