data Identity a = Identity {runIdentity :: a} instance Functor Identity where fmap f = Identity . f . runIdentity data Const a b = Const {getConst :: a} instance Functor (Const a) where fmap _ (Const a) = Const a type Lens s t a b = forall f . Functor f => (a -> f b) -> s -> f t view :: Lens s t a b -> s -> a view l = getConst . l Const over :: Lens s t a b -> (a -> b) -> s -> t over l f = runIdentity . l (Identity . f) set :: Lens s t a b -> b -> s -> t set l = over l . const _1 :: Lens (a, x) (b, x) a b _1 f (a, b) = (\a' -> (a', b)) <$> f a _2 :: Lens (x, a) (x, b) a b _2 f (a, b) = (\b' -> (a, b')) <$> f b main :: IO () main = putStrLn . show . view _1 . over _1 (++", World!") $ set _1 "Hello" ("ABC", "DEF")