Dual
is a newtype-wrapper that just reverses the order of mappend
for the wrapped type's Monoid
instance:
>>> "hello" <> " " <> "world"
"hello world"
>>> getDual $ Dual "hello" <> Dual " " <> Dual "world"
"world hello"
Equivalently, one could define a newtype-wrapper Swap
that reverses the order of <*>
for the wrapped type's Applicative
instance:
newtype Swap f a = Swap { getSwap :: f a } deriving Functor
instance Applicative f => Applicative (Swap f) where
pure = Swap . pure
Swap mf <*> Swap ma = Swap $ (\a f -> f a) <$> ma <*> mf
>>> ("hello", replicate) <*> (" ", 5) <*> ("world", ())
("hello world", [(),(),(),(),()])
>>> getSwap $ Swap ("hello", replicate) <*> Swap (" ",5) <*> Swap ("world", ())
("world hello", [(),(),(),(),()])
I could have sworn there was an equivalent to Swap
in base
, but I can't seem to find it. Is there an commonly-used equivalent in some other package?
You are looking for Backwards
, from transformers' Control.Applicative.Backwards
:
-- | The same functor, but with an 'Applicative' instance that performs
-- actions in the reverse order.
newtype Backwards f a = Backwards { forwards :: f a }
-- etc.
-- | Apply @f@-actions in the reverse order.
instance (Applicative f) => Applicative (Backwards f) where
pure a = Backwards (pure a)
{-# INLINE pure #-}
Backwards f <*> Backwards a = Backwards (a <**> f)
{-# INLINE (<*>) #-}
(<**>)
, from Control.Applicative
, is, as you'd expect:
-- | A variant of '<*>' with the arguments reversed.
(<**>) :: Applicative f => f a -> f (a -> b) -> f b
(<**>) = liftA2 (\a f -> f a)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With