Prism
is like Iso
except one of the two conversions is partial. Is there an optic where both conversions are partial?
Of course one can create a type (s -> Maybe a, b -> Maybe t)
but I'm wondering if such a thing could be expressed an as Optic _ _
?
You can generalize Iso
s (i.e., (s -> a, b -> t)
) into (s -> m a, b -> m t)
by replacing profunctors over Hask (i.e., Profunctor
, that's the constraint in the definition of Iso
as an Optic
) with profunctors over Kleisli categories (here for the Maybe
monad).
class Monad m => KProfunctor m p where
dimapM :: (s -> m a) -> (b -> m t) -> p a b -> p s t
-- dimapM pure pure = id
-- dimapM f g . dimapM h i = dimapM (h >=> f) (g >=> i)
type Optic p s t a b = p a b -> p s t
type KIso m s t a b = forall p. KProfunctor m p => Optic p s t a b
To construct one example of such profunctor, take the type of pseudo-isos (s -> m a, b -> m t)
that we are trying to work with in the first place, and put s
and t
as the main indices:
data PseudoIso m a b s t = MkPseudoIso
{ toM :: s -> m a
, fromM :: b -> m t
}
instance Monad m => KProfunctor m (PseudoIso m) where
-- exercise for the reader
PseudoIso
to KIso
, use dimapM
(the fields of PseudoIso
are exactly the right type for the arguments of dimapM
)KIso
to PseudoIso
, partially apply to the identity PseudoIso a b a b
Actually, it doesn't have to be a Kleisli category. A profunctor over any category (:->) :: k -> k -> Type
will give you a class of optics of the form (s :-> a, b :-> t)
.
Note: you can define an instance of Choice
with KProfunctor Maybe
, so maybe everything should really be specialized to Maybe
so Choice
could reasonably be added as a superclass of KProfunctor
, then KIso
would be a subtype of Prism
.
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