David Feuer
2018-08-11 17:19:20 UTC
We currently offer liftA, liftM, liftM2, and ap to implement Functor and
Applicative methods in terms of Applicative and Monad ones. But there are a
couple other functions in that general vein that are missing. I propose
that we should add at least replaceA, and perhaps also beforeM.
-- (<$) = replaceA
-- This may be better than the default if there is
-- an optimized definition of *> (which may be
-- based on an optimized >>).
replaceA :: Applicative f => a -> f x -> f a
replaceA a fa = fa *> pure a
-- (<*) = beforeM
-- This may be better than the default if there is
-- an optimized definition of <$, or if <$ is defined as
-- replaceA and *> is optimized.
beforeM :: Monad f => f a -> f x -> f a
beforeM fa fx = fa >>= \a -> a <$ fx
Why a <$ fx and not fx >> pure a? Because <$ could be implemented
specially, and is unlikely to be implemented by hand using <* if there
isn't a custom <*.
Applicative methods in terms of Applicative and Monad ones. But there are a
couple other functions in that general vein that are missing. I propose
that we should add at least replaceA, and perhaps also beforeM.
-- (<$) = replaceA
-- This may be better than the default if there is
-- an optimized definition of *> (which may be
-- based on an optimized >>).
replaceA :: Applicative f => a -> f x -> f a
replaceA a fa = fa *> pure a
-- (<*) = beforeM
-- This may be better than the default if there is
-- an optimized definition of <$, or if <$ is defined as
-- replaceA and *> is optimized.
beforeM :: Monad f => f a -> f x -> f a
beforeM fa fx = fa >>= \a -> a <$ fx
Why a <$ fx and not fx >> pure a? Because <$ could be implemented
specially, and is unlikely to be implemented by hand using <* if there
isn't a custom <*.