Most of instance Applicative (FooT r m) in transformers do not define liftA2 and, since it's not defined, do not supply {-# INLINE liftA2 #-} pragma. It's not too bad usually: liftA2 gets its default definition from class Applicative, which is small enough to be likely inlined by GHC automatically. Yet it would be cleaner not to rely on this and force inlining (which is crucial for efficiency of monad transformers) outselves.
Here is a typical example with all methods from Applicative except liftA2 defined explicitly and having {-# INLINE #-} pragma:
|
instance (Monad m) => Applicative (StateT s m) where |
|
pure a = StateT $ \ s -> return (a, s) |
|
{-# INLINE pure #-} |
|
StateT mf <*> StateT mx = StateT $ \ s -> do |
|
~(f, s') <- mf s |
|
~(x, s'') <- mx s' |
|
return (f x, s'') |
|
{-# INLINE (<*>) #-} |
|
m *> k = m >>= \_ -> k |
|
{-# INLINE (*>) #-} |
I don't think there is any reason for the existing behaviour other than historical ones: liftA2 was not a member of class Applicative prior to base-4.10. Since we no longer support base < 4.10, I'd suggest to rectify the discrepancy.
Most of
instance Applicative (FooT r m)intransformersdo not defineliftA2and, since it's not defined, do not supply{-# INLINE liftA2 #-}pragma. It's not too bad usually:liftA2gets its default definition fromclass Applicative, which is small enough to be likely inlined by GHC automatically. Yet it would be cleaner not to rely on this and force inlining (which is crucial for efficiency of monad transformers) outselves.Here is a typical example with all methods from
ApplicativeexceptliftA2defined explicitly and having{-# INLINE #-}pragma:transformers/Control/Monad/Trans/State/Lazy.hs
Lines 207 to 216 in 86d9fbd
I don't think there is any reason for the existing behaviour other than historical ones:
liftA2was not a member ofclass Applicativeprior tobase-4.10. Since we no longer supportbase < 4.10, I'd suggest to rectify the discrepancy.