r6research (r6research) wrote,

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)
  PStore g f = l (PStore id) id

  • Post a new comment


    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 1 comment
Categorically, it's pretty trivial, take the cone, tweak it a little bit.