我有一种类型想用作状态monad的一部分:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data SomeState = SomeState
{ _int :: Int,
_string :: String }
makeLenses ''SomeState
我具有对SomeState
中的部分状态进行操作的函数。假设他们还使用状态monad:
updateInt :: Int -> State Int ()
updateString :: String -> State String ()
在顶层,我有一个处理整个SomeState
的函数。
updateSomeState :: Int -> State SomeState ()
我想将updateInt
和updateString
称为updateSomeState
的一部分。我觉得应该可以使用lense将SomeState状态单子“转换”为其中一部分的状态单子,但我不知道如何。
感谢您的帮助。
答案 0 :(得分:1)
我相信您可以使用zoom
中的Control.Lens.Zoom
组合器来做到这一点:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
import Control.Monad.State
data SomeState = SomeState { _int :: Int, _string :: String } deriving (Show)
makeLenses ''SomeState
updateInt :: Int -> State Int ()
updateInt x = id .= x
updateString :: String -> State String ()
updateString x = id .= x
updateSomeState :: Int -> State SomeState ()
updateSomeState x = zoom int (updateInt x)
GHCi:
*Main> runStateT (updateSomeState 5) (SomeState 3 "hi")
Identity ((),SomeState {_int = 5, _string = "hi"})