From Van Laarhoven Isomorphisms in one shot.
The type ∀ f, g : Functor. (g a → f b) → g s → f t
is isomorphic to the type (s → a)×(b → t)
. The Van Laarhoven representation of isomorphisms uses this representation of a pair of function to capture the notion of an isomorphism.
Given a value of type ∀ f, g : Functor. (g a → f b) → g s → f t
, the normal way of extracting the two components is to instantiate the value twice using Identity
and Constant
functors.
extractPair :: (forall f g. (Functor f, Functor g) => (g a -> f b) -> g s -> f t) -> (s -> a, b -> t) extractPair l = (getConstant . (l (Constant . runIdentity)) . Identity ,runIdentity . (l (Identity . getConstant)) . Constant)
However, it is possible to extract the two components in one shot.
data PStore i j x = PStore {peek :: j -> x, pos :: i} instance Functor (PStore i j) where fmap f (Pstore h i) = PStore (f . h) i extractPair :: (((s -> a) -> PStore (s -> a) b b) -> (s -> s) -> PStore (s -> a) b t) -> (s -> a, b -> t) extractPair l = (f, g) where PStore g f = l (PStore id) id