【发布时间】:2020-03-29 14:10:22
【问题描述】:
我正在尝试定义一个状态机系列,它们具有一些不同的状态。特别是,更“复杂”的状态机具有通过组合更简单状态机的状态而形成的状态。
(这类似于面向对象的设置,其中一个对象具有多个属性,这些属性也是对象。)
这是我想要实现的简化示例。
data InnerState = MkInnerState { _innerVal :: Int }
data OuterState = MkOuterState { _outerTrigger :: Bool, _inner :: InnerState }
innerStateFoo :: Monad m => StateT InnerState m Int
innerStateFoo = do
i <- _innerVal <$> get
put $ MkInnerState (i + 1)
return i
outerStateFoo :: Monad m => StateT OuterState m Int
outerStateFoo = do
b <- _outerTrigger <$> get
if b
then
undefined
-- Here I want to "invoke" innerStateFoo
-- which should work/mutate things
-- "as expected" without
-- having to know about the outerState it
-- is wrapped in
else
return 666
更一般地说,我想要一个通用框架,其中这些嵌套更复杂。这是我想知道的事情。
class LegalState s
data StateLess
data StateWithTrigger where
StateWithTrigger :: LegalState s => Bool -- if this trigger is `True`, I want to use
-> s -- this state machine
-> StateWithTrigger
data CombinedState where
CombinedState :: LegalState s => [s] -- Here is a list of state machines.
-> CombinedState -- The combinedstate state machine runs each of them
instance LegalState StateLess
instance LegalState StateWithTrigger
instance LegalState CombinedState
liftToTrigger :: Monad m, LegalState s => StateT s m o -> StateT StateWithTrigger m o
liftToCombine :: Monad m, LegalState s => [StateT s m o] -> StateT CombinedState m o
就上下文而言,这就是我想用这台机器实现的目标:
我想设计这些叫做“流转换器”的东西,它们基本上是有状态的函数:它们消耗一个令牌,改变它们的内部状态并输出一些东西。具体来说,我对输出为布尔值的一类流转换器感兴趣;我们将这些称为“监视器”。
现在,我正在尝试为这些对象设计组合器。其中一些是:
-
pre组合器。假设mon是一个监视器。然后,pre mon是一个监视器,它总是在第一个令牌被消耗后产生False,然后模仿mon的行为,就好像现在正在插入前一个令牌一样。我想在上面的示例中使用StateWithTrigger对pre mon的状态进行建模,因为新状态与原始状态一样是布尔值。 -
and组合器。假设m1和m2是监视器。然后,m1 `and` m2是一个监视器,它将令牌提供给 m1,然后提供给 m2,如果两个答案都为真,则生成True。我想在上面的示例中使用CombinedState对m1 `and` m2的状态进行建模,因为必须保持两个监视器的状态。
【问题讨论】:
-
仅供参考,
_innerVal <$> get只是gets _innerVal(如gets f == liftM f get和liftM只是fmap专门用于 monads)。 -
您从哪里获得
StateT InnerState m Int值在outerStateFoo中的首位? -
您对镜头感到满意吗?这个用例似乎正是
zoom的用途。 -
@Carl 我看过一些镜头,但不是很了解。也许您可以在答案中解释如何使用缩放?
-
观察:此条目不包含一个问题。
标签: haskell state monads monad-transformers state-monad