{-# 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