Skip to content

Instantly share code, notes, and snippets.

@ion1
Last active June 16, 2019 06:00
Show Gist options
  • Save ion1/5a38dd315e093c382cb5 to your computer and use it in GitHub Desktop.
Save ion1/5a38dd315e093c382cb5 to your computer and use it in GitHub Desktop.
Mini lens
{-# LANGUAGE RankNTypes #-}
import Control.Applicative
import Data.Functor.Identity
import Data.Monoid
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t
_1 :: Lens (a,b) (a',b) a a'
_1 f (a,b) = (\a' -> (a',b)) <$> f a
_2 :: Lens (a,b) (a,b') b b'
_2 f (a,b) = (\b' -> (a,b')) <$> f b
both :: Traversal (a,a) (b,b) a b
both f (a,b) = (,) <$> f a <*> f b
traverse' :: Traversal [a] [b] a b
traverse' f (x:xs) = (:) <$> f x <*> traverse' f xs
traverse' _ [] = pure []
type Setting s t a b = (a -> Identity b) -> s -> Identity t
type Getting r s a = (a -> Const r a) -> s -> Const r s
over :: Setting s t a b -> (a -> b) -> s -> t
over l f s = runIdentity (l (Identity . f) s)
view :: Getting a s a -> s -> a
view l s = getConst (l Const s)
toListOf :: Getting [a] s a -> s -> [a]
toListOf l s = getConst (l (Const . (\x -> [x])) s)
sumOf :: Getting (Sum a) s a -> s -> a
sumOf l s = getSum (getConst (l (Const . Sum) s))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment