How do I avoid referring to all state variables when updating only a few?

后端 未结 3 724
名媛妹妹
名媛妹妹 2021-01-07 20:04

An idiom I use for composing a couple of procedures (with memory) is as follows:

p1 :: State (Int, String) ()
p1 = do
    (a, b) <- get
    ... do somethi         


        
3条回答
  •  天涯浪人
    2021-01-07 20:32

    This seems like a job for lenses. Especially the Control.Lens.Tuple module together with .= and use:

    p1 = do
       a <- use _1
       -- do something --
       _1 .= a'
    

    However, it's usually better if you give the things in your state proper names, e.g.

    {-# LANGUAGE TemplateHaskell #-
    
    data Record = MkRecord { _age :: Int
                           , _name :: String
                           , _programmer :: Bool
                           } deriving (Show, Eq)
    makeLenses ''Record
    

    That way, you have better names for your field:

    p1 = do
       a <- use age
       -- do something --
       age .= a'
    

    Note that this still helps you if you don't want to use lenses, since you can use record syntax to update your data:

     p1 = do
          r <- get
          let a = _age r
          --- do something
          put $ r{_age = a'}
    

提交回复
热议问题