Haskell var <- get 是什么意思?

标签 haskell

我遇到了这段代码,但我不知道 grid <- get 的作用是什么?做?我们怎么知道这个网格就是我们当前的网格呢?我们不会将其作为参数传递。那么我们如何使用它来抓取行呢?

data Grid = Grid [Row]
type GridState a = State Grid a

initializeGrid :: GridState ()
initializeGrid = do
        setPositionToColor 2 0 Alive


setPositionToColor :: Int -> Int -> CellState -> GridState ()
setPositionToColor x y color = do
        grid <- get
        let rows = getRows grid
            ...
        put newState

getRows :: Grid -> [Row]
...

最佳答案

State monad 有效地隐藏了这样一个事实:每个函数都将状态值作为输入,并在输出中包含(可能已更改的)状态。 get 实际上只是返回隐藏的参数。

如果您在编写函数时不使用 State,结果会更清晰。

-- State Grid a == Grid -> (Grid, a)
setPositionToColor :: Int -> Int -> Color -> Grid -> (Grid, ())
                                             ^^^^^^^^^^^^^^^^^^

当您调用setPositionToColor 2 0 Alive时,您实际上并没有为网格的任何特定元素着色,因为还没有涉及网格。您只需返回一个函数,当使用 Grid 调用it时,将生成新修改的Grid

如果没有 Monad 实例,每次调用 setPositionToColor 都需要该附加参数,并且它将返回一个新的 Grid 传递给下一个电话。你的代码看起来像

let (grid1,_) = setPositionToColor x1 y1 color1 initialGrid
    (grid2,_) = setPositionToColor x2 y2 color2 grid1
    (grid3,_) = setPositionToColor x3 y3 color3 grid2
    (grid4,_) = setPositionToColor x4 y4 color4 grid3
in grid4
<小时/>

Monad 实例所做的一切就是负责将中间的 Grid 值从一个函数传递到下一个函数;您需要做的就是提供 initialGrid 作为 runState 的参数,它实际上启动对组合 State 操作的调用。

-- Back to setPositionToColor :: Int -> Int -> Color -> State Grid a
let allFour = setPositionToColor x1 y1 color1 >>= (\() ->
              setPositionToColor x2 y2 color2 >>= (\() ->
              setPositionToColor x3 y3 color3 >>= (\() ->
              setPositionToColor x3 y3 color4)))
in runState allFour initialGrid

或者,因为我们实际上并不关心每次调用返回的 () 值,

let allFour = setPositionToColor x1 y1 color1 >>
              setPositionToColor x2 y2 color2 >>
              setPositionToColor x3 y3 color3 >>
              setPositionToColor x3 y3 color4
in runState allFour initialGrid

使用do表示法,

let allFour = do
   setPosition x1 y1 color1
   setPosition x2 y2 color2
   setPosition x3 y3 color3
   setPosition x4 y4 color4
in runState allFour initialGrid

关于Haskell var <- get 是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47930334/

相关文章:

multithreading - 使用forkIO在Haskell "Concurrently, Asynchronously, Parallel, Non-Blocking"中进行Network.Socket编程

haskell - 在haskell中为元组列表分配等级

haskell - 对 LLVM 的外部导入 prim 调用

haskell - 特征函数的类型别名

string - 将前导零的haskell Int转换为String

haskell - 为什么我可以使用这个 "private"值构造函数?

Haskell:为什么这段代码会失败?

parsing - 如何在 Haskell 中将 Haskell 源代码解析为 AST?

haskell - 带有 4 个参数的foldr?

haskell - 在 Cygwin 中编译 Haskell 代码,以及 Windows 上 Haskell 平台中的一些其他错误