Implementation of liftA2 for Const has high arity
instance Monoid m => Applicative (Const m) where
pure _ = Const mempty
liftA2 _ (Const x) (Const y) = Const (x `mappend` y)
(<*>) = coerce (mappend :: m -> m -> m)
https://hackage.haskell.org/package/base-4.10.1.0/docs/src/Data.Functor.Const.html#line-69
(<*>)
is implemented with a coerce
but liftA2
isn't. Would the following not have better inlining behavior?
liftA2 _ = coerce (mappend :: m -> m -> m)
Going further, should the unused argument also be moved to the RHS? What about pure
? What are the pros and cons compared to this other alternative:
pure = \_ -> Const mempty
liftA2 = \_ -> coerce (mappend :: m -> m -> m)
This came up while implementing Applicative
for K1
in phab:D4447. K1
is essentially the same type as Const
and thus their instances should be identical for the sake of consistency. But it's not clear to me whether Const
's Applicative
instance is already optimal. Is it?