Haskell Lens Idea
A lens is a getter and a setter for one field, kept together as one tool. It names one part of a larger value so that part can be read and replaced.
A getter reads one field
getX reads the x field of a point. The rest of the point is ignored.
data Point = Point { pointX :: Int, pointY :: Int } deriving Show
getX :: Point -> Int
getX (Point x _) = x
main :: IO ()
main = print (getX (Point 3 4))A setter replaces one field
setX builds a new point with a new x value. The y value stays the same.
data Point = Point { pointX :: Int, pointY :: Int } deriving Show
setX :: Int -> Point -> Point
setX v (Point _ y) = Point v y
main :: IO ()
main = print (setX 9 (Point 3 4))Get and set work on the same field
The getter reads the value that the setter can replace. Adding one to the read value moves the point by one.
data Point = Point { pointX :: Int, pointY :: Int } deriving Show
getX :: Point -> Int
getX (Point x _) = x
setX :: Int -> Point -> Point
setX v (Point _ y) = Point v y
main :: IO ()
main = print (setX (getX (Point 3 4) + 1) (Point 3 4))Example
data Point = Point { pointX :: Int, pointY :: Int } deriving Show
setX :: Int -> Point -> Point
setX v (Point _ y) = Point v y
setY :: Int -> Point -> Point
setY v (Point x _) = Point x v
main :: IO ()
main = print (setY 20 (setX 10 (Point 3 4)))Key points
- Lens: a getter and a setter for one field, thought of as one tool.
- Getter: a function that reads one field from a record.
- Setter: a function that replaces one field and keeps the other fields unchanged.
- Field: one named part of a record.
- Use getX to read the x field and setX to replace it.
In this example, setX first replaces the x field with 10, then setY replaces the y field with 20, and the printed point shows both new fields with nothing else changed.
Note
a lens builds a new record with one field changed and leaves the original record unchanged.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Haskell Playground
Exercise
What does setX 9 (Point 3 4) return?