Skip to content

Instantly share code, notes, and snippets.

@Lazersmoke
Created May 30, 2016 21:05
Show Gist options
  • Save Lazersmoke/06c00d5dc3d0836742fcafe92736f70b to your computer and use it in GitHub Desktop.
Save Lazersmoke/06c00d5dc3d0836742fcafe92736f70b to your computer and use it in GitHub Desktop.
This is my off-the-top-off-my-head lightweight lens alternative
-- Data decls could be in their own module for qualified import?
-- Alternatively, there might be a solution in GHC 8's duplicate record fields...
-- Only thing to update to add fields is the accessor functions
-- Test with an int and a str
data Test = MkTest Integer String deriving (Eq,Show)
number :: Access Integer Test
number f (MkTest n s) = (f n, MkTest (f n) s)
str :: Access String Test
str f (MkTest n s) = (f s, MkTest n (f s))
-- Kitten with a name, an age and a list of favorite words
-- Example: grab name (Kitten "Techy" 5 ["Meow","Mew"]) == "Techy"
-- Example: change age succ (Kitten "Techy" 5 ["Meow","Mew"]) == Kitten "Techy" 6 ["Meow","Mew"]
data Kitten = Kitten String Integer [String] deriving (Eq,Show)
name :: Access String Kitten
name f (Kitten n a w) = (f n, Kitten (f n) a w)
age :: Access Integer Kitten
age f (Kitten n a w) = (f a, Kitten n (f a) w)
favWords :: Access [String] Kitten
favWords f (Kitten n a w) = (f w, Kitten n a (f w))
-- In library
type Access a b = (a -> a) -> b -> (a, b)
grabf :: Access a b -> (a -> c) -> b -> c
grabf a f m = f $ grab a m
grab :: Access a b -> b -> a
grab a m = fst $ a id m
change :: Access a b -> (a -> a) -> b -> b
change a f m = snd $ a f m
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment