使用州monad没有" get"函数

时间:2017-12-23 16:23:23

标签: haskell

this关于镜片的好文章中,Gabriel Gonzalez写了这段代码:

import Control.Monad.Trans.Class
import Control.Monad.Trans.State

strike :: StateT Game IO ()
strike = do
        lift $ putStrLn "*shink*"
        boss.health -= 10

但后来写了

newState^.boss.health

我知道为了修改State monad(这里是StateT monad变换器)你需要使用get函数获取状态,用它做一些事情,并且然后使用put函数。但是这里作者没有使用这些功能。同样在第二个示例中,他使用^运算符,这意味着要使用boss镜头,您需要Game值。但他在第一个例子中没有这样做。怎么样?

1 个答案:

答案 0 :(得分:8)

让我们看一下boss.health -= 10行。 -=包中的lensdefined

(-=) :: (MonadState s m, Num a) => ASetter' s a -> a -> m ()
l -= b = State.modify (l -~ b)

关于这个定义的两点:

  1. 它不使用get / put,而是modify,其中modify f相当于get x >>= \x -> put (f x)

  2. 第一个参数是ASetter' s a。镜头,特别是文章所用的boss.health,可以起作用。操作员说:“我将使用你通过的镜头减去状态值。”