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