{-# LANGUAGE RankNTypes #-} -- Traditional lens as a pair of getter and setter type Lens a b = (b -> a, b -> a -> b) -- Lens implemented with a store comonad data Store a b = Store { get :: a, set :: a -> b } instance Functor (Store a) where fmap f (Store a ab) = Store a (f . ab) type SLens a b = b -> Store a b -- Van Laarhoven lens type VLLens a b = forall g . Functor g => (a -> g a) -> (b -> g b) -- Lens / SLens isomorphism lensToSlens :: Lens a b -> SLens a b lensToSlens (getter, setter) = \b -> Store (getter b) (setter b) sLensToLens :: SLens a b -> Lens a b sLensToLens slens = (get . slens, set . slens) -- SLens / VLLens isomorphism sLensToVLLens :: SLens a b -> VLLens a b sLensToVLLens slens = \f b -> let Store a ab = slens b in fmap ab $ f a vLLensToSLens :: VLLens a b -> SLens a b vLLensToSLens vllens = \b -> ((flip vllens) b) (\a -> Store a id)
Saturday, 12 October 2013
Haskell Lens Isomorphisms
A small snippet of code I wrote to try and get my head around Van Laarhoven lenses. It shows the isomorphisms between three common representations of lenses.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment