You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I propose updates on the documentation of Control.Monad.Free.Ap module to tell
the Free f monad in this module should be interpreted using a commutative (or "morally" commutative) Monad.
The Free f monad in the Control.Monad.Free.Ap module is to provide an optimization for some usages (e.g. Haxl-like monad having concurrent <*>), while it doesn't obey the law requiring (<*>) = ap in the eyes of strict equality.
The current documentation of Control.Monad.Free.Ap module states
the loosened law hold under the interpretation of foldFree fif f is
an applicative homomorphism. I think it's written as if the following statement is true.
If f is an applicative homomorphism, foldFree f (x <*> y) = foldFree f (x `ap` y)
But it doesn't hold. Let foo, bar be the following values of Free IO monad.
Then retract (foo <*> bar) and retract (foo `ap` bar) print out strings in different order. Since retract = foldFree id and id :: IO a -> IO a is an applicative homomorphism without doubt, the above statement about the lawfulness of Free f is too optimistic.
Generally, retract (x `ap` y) = retract x `ap` retract y = retract x <*> retract y hold. So the loosened law is equivalent to retract (foo <*> bar) = retract foo <*> retract bar. This is again equivalent to say the monad f in retract :: Free f a -> f a is a commutative monad. In terms of foldFree f, I think "f must be an applicative homomorphism to a commutative monad" is appropriate.
Of course, the primary usage of Haxl-like monad isn't commutative in the strictest sense,
but it's "morally" commutative because they're best used when the ordering of effects do not matter.
The text was updated successfully, but these errors were encountered:
I propose updates on the documentation of
Control.Monad.Free.Ap
module to tellthe
Free f
monad in this module should be interpreted using a commutative (or "morally" commutative) Monad.The
Free f
monad in theControl.Monad.Free.Ap
module is to provide an optimization for some usages (e.g. Haxl-like monad having concurrent<*>
), while it doesn't obey the law requiring(<*>) = ap
in the eyes of strict equality.The current documentation of
Control.Monad.Free.Ap
module statesthe loosened law hold under the interpretation of
foldFree f
iff
isan applicative homomorphism. I think it's written as if the following statement is true.
But it doesn't hold. Let
foo, bar
be the following values ofFree IO
monad.Then
retract (foo <*> bar)
andretract (foo `ap` bar)
print out strings in different order. Sinceretract = foldFree id
andid :: IO a -> IO a
is an applicative homomorphism without doubt, the above statement about the lawfulness ofFree f
is too optimistic.Generally,
retract (x `ap` y) = retract x `ap` retract y = retract x <*> retract y
hold. So the loosened law is equivalent toretract (foo <*> bar) = retract foo <*> retract bar
. This is again equivalent to say the monadf
inretract :: Free f a -> f a
is a commutative monad. In terms offoldFree f
, I think "f
must be an applicative homomorphism to a commutative monad" is appropriate.Of course, the primary usage of
Haxl
-like monad isn't commutative in the strictest sense,but it's "morally" commutative because they're best used when the ordering of effects do not matter.
The text was updated successfully, but these errors were encountered: