---
# System prepended metadata

title: Motivation

---

# Motivation
- lensにできる一番単純なこと：深くネストしたレコードを更新すること
  - 例：
  ```
  data Atom = Atom{_element :: String, _point :: Point}
  
  data Point = Point{_x :: Double ,_y :: Double}
  ```
  - Atomデータのx座標を1だけ増やしたければ、次のように書くことになる：
  ```
  shiftAtomX :: Atom -> Atom
  shiftAtomX (Atom e (Point x y)) = Atom e (Point (x+1) y)
  ```
- レコードの値がもっと多かったり、ネストがもっと深ければ、この手の操作は困難を増す
- lensライブラリはそれを解決できる
  ```
  {-# LANGUAGE TemplateHaskell #-}
  
  import Control.Lens hiding(element)
  import Control.Lens.TH
  
  data Atom = Atom{_element :: String, _point :: Point} deriving(Show)
  
  data Point = Point{_x :: Double ,_y :: Double} deriving(Show)
  
  
  $(makeLenses ''Atom)
  $(makeLenses ''Point)
  
  shiftAtomX :: Atom -> Atom
  shiftAtomX = over (point . x) (+1)
  ```
  
  ```
  >>> let atom = Atom{_element = "C", _point = Point{_x = 1.0,_y = 2.0}}
  >>> shiftAtomX atom
  Atom{_element = "C", _point = Point{_x = 2.0, _y = 2.0}}
  ```
  - この関数は、AtomやPointのフィールド数に依らず動く
  
  - 別の例
    ```
    data Morecule = Molecule { _atom :: [Atom]} deriving(Show)
    ```
    - Moreculeの値を一気に動かす
    ```
    $(makeLenses ''Morecule)
    
    shiftMoreculeX :: Morecule -> Morecule
    shiftMoreculeX = over (atoms . traverse . point . x) (+1)
    ```
    - ※traverseがmapみたいに動いてるんだろうけど、atoms,pointの使われ方がどういうこっちゃ
- 多くの人が、膨大なフィールドやどん深のネストを扱おうとしてLensに巡り会う


