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