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