Unknown syntax to modify Haskell Record
  data Person = Person {
	name :: String,
	age :: Int
  } deriving (Show, Eq)

  modifyAge :: (Int -> Int) -> Person ->  Person
  modifyAge f p@(Person _ a) = p {age = f a}

  let p = Person {name = "Rebecca", age = 18}
  let p1 = modifyAge (+1) p
  print p1

  // Set age
  let p2 = modifyAge (const 30) p
  print p2
Modify Haskell Record 2
  modifyPerson :: (Int -> Int) -> Person -> Person
  modifyPerson f p = (\x -> p {age = x}) $ f $ age p
                            ↑
                            + -> Person {age = x, name = name p}
  
                 p    /=    p
                 ↑
                 + -> Two p are different
                 
Haskell Type Constructor is just a function
    data MyType = R Int String | S Int Int deriving (Show)

    :t R 
    R::Int →  String → MyType
    :t S
    S::Int → Int → MyType
Haskell Record is just a function too
    data Rec a = Rec{runRec :: String → [(a, String)]}
    :t runRec
    runRec :: Rec a → String → [(a, String)]

    -- We can define a "same" function like runRec

    getRec :: Rec a → String → [(a, String)]
    getRec (Rec f) = f

    -- It is the same
    getRec :: Rec a → String → [(a, String)]
    getRec (Rec f) s = f s
Understand runState in State monad
Once we understand Rec a, runState is the same as getRec or runRec
    newtype StateX s a = StateX{runStateX :: s → (a, s)}
    :t runStateX 

    -- runStatex becomes the following function
    runStateX :: StateX s a → s → (a, s)

    -- write your own function for runStateX
                     + → Type Constructor
                     ↓              
    getStateX :: (StateX s a) → s → (a, s)

    getStateX (StateX f) s = f s 
                   ↑  ↑ 
                   |  + ⟹   f :: s → (a, s)
                   |
                   + → Value Constructor

    getStateX (StateX f) = f
        ↑ 
        |
        + → Unwrap/UnBoxed StateX to access f

    -- GHC generate runStateX like getStateX ?

    let ss = StateX (\s → ("abc", s))  -- Use the Value Constructor to create a type StateX s String 
    :i ss
    ss :: (String a) ⟹  StateX s a 

    -- Or we can pass a function to StateX
    let g = \s → ("abc", s)
    let st = StateX g
    :i st 
    st :: (String a) ⟹  StateX s a
    Implement an instance of Monad 
    instance Monad (StateX s) where
        return a = StateX (\s → (a, s)) -- Keep the same state and a
        (>>=) (StateX g) f = StateX (\s →  let (a, ns) <- g s in runStateX (f a) ns
                         ↑                                ↑      ↑           ↑
                         |                                |      |           + → (a -> m b) a ⟹  m b
                         |                                |      |              
                         + → f :: (a -> m b)              |      |            
                                                          |      |
                                                          |      + →  runStateX (m b) ⟹   \s → (b, s)   ∵  runStateX (StateX f) = f ⟹  runStateX (StateX (\s → (b, s)) = \s → (b, s)
                                                          |                       ↑ 
                                                          |                       + → StateX s b = StateX(\s → (b, s))
                                                          |                           |----+-|
                                                          |                                ↓ 
                                                          |                                + → m 
                                                          |                            
                                                          |                           |---------|
                                                          |                                | 
                                                          |                                ↓ 
                                                          |                                + → m b 
                                                          |                         
                                                          |      ├- - - - + - - - - ┤ 
                                                          |               |
                                                          |               ↓ 
                                                          |           runStateX (StateX f) = f
                                                          |                       ↓  
                                                          |           runStateX (StateX (\s → (b, s))     = \s → (b, s)
                                                          |
                                                          |           runStateX (StateX (\ns → (b, s)) ns = \ns → (b, ns) ns ⟹  (b, ns)
                                                          |
                                                          |         
                                                          |               
                                                          |               
                                                          |
                                                          + → g::s → (a, s)