strictly :: (Profunctor p, Profunctor q, Functor f) => Optical p q (BoxT f) s t a b -> Optical p q f s t a b
strictly l f = rmap (fmap getSolo .# runBoxT) $ l (rmap (BoxT #. fmap (Solo $!)) f)
where BoxT is the following applicative transformer:
newtype BoxT f a = BoxT { runBoxT :: f (Solo a) }
deriving Functor
instance Apply f => Apply (BoxT f) where
liftF2 f (BoxT m) (BoxT n) = BoxT (liftF2 (liftA2 f) m n)
instance Applicative f => Applicative (BoxT f) where
pure = BoxT . fmap Solo
liftA2 f (BoxT m) (BoxT n) = BoxT (liftA2 (liftA2 f) m n)
-- The Contravariant instance probably isn't really useful (strictifying
-- a getter or fold doesn't change anything) but it at least *seems*
-- harmless.
instance Contravariant f => Contravariant (BoxT f) where
contramap f (BoxT m) = BoxT (contramap (fmap f))
-- BoxT intentionally does *not* have a Settable instance,
-- because it's impossible to strictify things like `mapped` that
-- are really just setters.
I figured you might be interested in doing something similar here.
I'm currently working on a PR for
lens
that addswhere
BoxT
is the following applicative transformer:I figured you might be interested in doing something similar here.