Skip to content

Instantly share code, notes, and snippets.

@nurpax
Created April 15, 2014 22:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nurpax/10784824 to your computer and use it in GitHub Desktop.
Save nurpax/10784824 to your computer and use it in GitHub Desktop.
proof that Control.Lens rules
name: lens-test
version: 0.1
license: AllRightsReserved
build-type: Simple
cabal-version: >=1.8
executable lens-test
hs-source-dirs: .
main-is: Test.hs
build-depends: base >= 4.5 && < 5
, lens
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data A = A {
_aId :: Int
, _bs :: [B]
} deriving (Show)
data B = B {
_bId :: Int
, _rects :: [Rect]
} deriving (Show)
data Rect = Rect {
_left :: Int
, _top :: Int
, _width :: Int
, _height :: Int
} deriving (Show)
makeLenses ''A
makeLenses ''B
makeLenses ''Rect
area :: Rect -> Int
area r = _width r * _height r
aRectangles = bs . traverse . rects
doubleWidths :: [A] -> [A]
doubleWidths = map (\a -> a { _bs = doubleBs . _bs $ a })
where
doubleBs = map (\b -> b { _rects = map (\r -> r { _width = 2 * _width r }) . _rects $ b })
t :: [A]
t = [A 13 [ B 3 [Rect 0 0 5 10, Rect 1 1 1 1]
, B 4 [Rect 1 1 1 1, Rect 1 1 5 5, Rect 2 2 8 8]
]
]
main = do
print t
print (t ^.. traverse . aRectangles)
-- Double width of each rect
print ([Rect 0 0 5 5, Rect 1 1 2 2] ^.. traverse)
print ([Rect 0 0 5 5, Rect 1 1 2 2] ^.. traverse . width)
putStrLn "\ndouble widths of rects"
print ([Rect 0 0 5 5, Rect 1 1 2 2] & each . width %~ (*2))
putStrLn "\ndouble widths - map map, ..., map"
print . doubleWidths $ t
putStrLn "\ndouble widths - each lens"
print (t & each . bs . each . rects . each . width %~ (*2))
putStrLn "\nfilter - include only area == 1 rects"
print (t & each . bs . each . rects %~ filter (\r -> area r < 2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment