实施州立Monad [英] Implementation of State Monad

查看:78
本文介绍了实施州立Monad的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一个简单的示例,以在Haskell中实现状态monad.我已经使用记录语法将数据类型设置为GlobState.函数incr1,incr2和incr3用于增加相应的记录元素.我写的代码是:

I am working on a simple example to implement the state monad in Haskell. I have made a data type GlobState using record syntax. Functions incr1, incr2 and incr3 are there to increment the respective record elements. The code i have written is:

module StateExample where
import Control.Monad.State

data GlobState = GlobState { c1 :: Int, c2:: Int, c3:: Int} deriving (Show)

newGlobState:: GlobState
newGlobState = GlobState { c1=0,c2=0,c3=0 }

--incr1 :: State GlobState ()
incr1 = do
    gets c1
    modify (+1)

--incr2 :: State GlobState ()
incr2 = do
    gets c2
    modify(+1)

incr3 = do
    gets c3
    modify(+1)

main =  do
    let ((),a1) = flip runState newGlobState $ do
        x<- incr1
        y<- incr2 x
        z<- incr1 y
        return z
    print a1

该程序没有提供所需的输出.而且我不确定增量函数的签名或gets是否正在执行我打算做的事情.请帮忙.

This program is not giving the desired output. And i am not sure about the signature of increment functions or if gets is doing what i intend to do. Please help.

我该如何对代码进行更改,以使我不必只定义一个增量函数,而不必定义不同的增量函数.我打算这样做:

How can i make changes to the code so that instead of defining the different increment functions, i need to make only one increment function. i intend to do like:

incr :: String-> State GlobState ()
incr x = do
modify(\g -> g {x =x g + 1})

推荐答案

您的类型至少是正确的.

Your types are right, at least.

incr1 :: State GlobState ()
incr1 = modify (\state -> state {c1 = 1 + c1 state})

例如,如果您在State Int ()中工作,您的modify (+1)会很好,但我们不是.您似乎认为gets将以下几行内容集中在状态的特定字段上,但---并非如此.

Your modify (+1) would be fine if you were working in State Int (), say, but we're not. You seem to think that gets focusses the following lines onto a particular field of the state --- but it doesn't.

incr2incr3也需要进行类似的更改.

incr2 and incr3 need to be changed similarly.

关于main:

  1. 您需要正确缩进代码.您似乎希望print a1是外部do块的一部分,而不是内部do块的一部分.如果没有缩进,编译器将无法解决.
  2. 您正在(尝试)手动对该状​​态进行线程化,但是关于State的全部要点是它的单子管道/适用管道为您完成了该任务.
  1. You need to indent your code properly. You appear to want the print a1 to be part of the outer do block, but not part of the inner do block. Without indentation, the compiler cannot figure that out.
  2. You are (attempting to) manually thread the state, but the whole point about State is that its monadic/applicative plumbing does that for you.

main = do let ((), a1) = flip runState newGlobState $ do incr1
                                                         incr2
                                                         incr1
          print a1

这篇关于实施州立Monad的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆