Lensはゲッターとセッターが一緒になったもの。フィールド名だと思ってもいい。makeLenses
を使えば自分で定義した型のLensを作ってくれて便利。Lensをゲッターとして使いたければ^.
、セッターとして使いたければ.~
を使うと良い。age .~ 36
は年齢を36に変更する関数で、Man -> Man
になっている。
% runghc
{-# LANGUAGE TemplateHaskell#-}
import Control.Lens
data Man = Man { _name :: String, _age :: Int } deriving (Show, Eq, Ord)
emptyMan :: Man
emptyMan = Man { _name = "", _age = 0 }
makeLenses ''Man
main :: IO ()
main = do
print $ hiratara ^. age
putStrLn $ hiratara ^. name
return ()
where hiratara = (age .~ 36) . (name .~ "hiratara") $ emptyMan
結果。
36
hiratara
MonadState
に閉じ込めて使いたければ use
や .=
を使うとよい。
import Control.Lens
import Control.Monad.Trans
import Control.Monad.Trans.State
...
main :: IO ()
main = flip evalStateT emptyMan $ do
age .= 30
name .= "hiratara"
lift . print =<< use age
lift . putStrLn =<< use name
return ()