标签: state-monad

管理国家 - SICP第3章

我一直在研究计算机程序的结构和解释,并完成Haskell的练习.前两章很好(github上的代码),但第3章让我更难思考.

首先是谈论管理国家,以银行账户为例.他们定义一个函数make-withdraw通过

(define (make-withdraw balance)
    (lambda (amount)
        (if (>= balance amount)
            (begin (set! balance (- balance amount))
                balance)
            "Insufficient funds")))
Run Code Online (Sandbox Code Playgroud)

这样您就可以执行以下代码:

(define w1 (make-withdraw 100))
(define w2 (make-withdraw 100))

(w1 50)
50

(w2 70)
30

(w2 40)
"Insufficient funds"

(w1 40)
10
Run Code Online (Sandbox Code Playgroud)

我不确定如何在Haskell中模仿这个.我首先想到了一个使用State monad的简单函数:

import Control.Monad.State

type Cash    = Float
type Account = State Cash

withdraw :: Cash -> Account (Either String Cash)
withdraw amount = state makewithdrawal where
    makewithdrawal balance = if balance …
Run Code Online (Sandbox Code Playgroud)

state haskell sicp state-monad

11
推荐指数
1
解决办法
844
查看次数

Haskell中的并行monad地图?像parMapM这样的东西?

我正在寻找一种在ST-Monad中并行运行两个计算的方法.我正在构建一个相当大的数组(使用STUArray),我想并行执行.

到目前为止,我已经在stackoverflow上找到了这个这个 Q&A,但是第一个不适用于我的情况,因为它只处理纯代码而第二个处理IO monad - 但我处于State Thread中.

我也找到了monad-parallel包,但它要求我为ST设置一个'MonadParallel'实例.另外,单子面值包中只支持纯计算或IO单子.

有没有办法在ST内进行并行monadic计算?

parallel-processing monads haskell state-monad

11
推荐指数
1
解决办法
1082
查看次数

State Monad有多个州的价值观

考虑以下:

do
  x1 <- new 2
  set x1 3
  x2 <- get x1
  y1 <- new 10
  set y1 20
  y2 <- get y1
  return (x2 + y2)
Run Code Online (Sandbox Code Playgroud)

我想要这个结果23.有没有办法在纯Haskell中实现这样的东西,如果是这样的话怎么样?我理解STRef这样的事情,但我只是想在普通的Haskell中做到这一点(现在不担心效率).我认为我必须创建一个数据类型并使其成为实例Monad,但我不确定细节,所以一个有用的例子会有所帮助.

monads haskell state-monad

11
推荐指数
2
解决办法
1295
查看次数

在scalaz中堆叠StateT

我试图通过移植Dan Piponi本教程中的一些例子来了解Scala中的Monad Transformers:http: //blog.sigfpe.com/2006/05/grok-haskell-monad-transformers.html

我做了几件简单的事:

import Control.Monad.State
import Control.Monad.Identity

test1 = do
    a <- get
    modify (+1)
    b <- get
    return (a,b)

test2 = do
    a <- get
    modify (++"1")
    b <- get
    return (a,b)

go1 = evalState test1 0
go2 = evalState test2 "0" 
Run Code Online (Sandbox Code Playgroud)

变为:

import scalaz._, Scalaz._

val test1 = for {
  a <- get[Int]
  _ <- modify[Int](1+)
  b <- get
} yield (a,b)

val test2 = for {
  a <- get[String]
  _ <- modify[String](_ + …
Run Code Online (Sandbox Code Playgroud)

haskell scala state-monad monad-transformers scalaz

11
推荐指数
1
解决办法
666
查看次数

Haskell有助于理解这个状态monad代码:runState在哪里定义?

我是Haskell的新手并试图了解monad.我将通过此代码 将其放在这里以供快速参考

newtype State s a = State { runState :: s -> (a,s) }

instance Monad (State s) where
  return a = State $ \s -> (a, s)

  State act >>= k = State $ \s ->
    let (a, s') = act s
    in runState (k a) s'

get :: State s s
get = State $ \s -> (s, s)

put :: s -> State s ()
put s = State $ \_ -> ((), s)

modify …
Run Code Online (Sandbox Code Playgroud)

haskell state-monad

11
推荐指数
2
解决办法
1206
查看次数

理解Reader monad

我正在通过示例阅读Purescript并介绍了阅读Monad的部分.这个例子是这样的:

createUser :: Reader Permissions (Maybe User)
createUser = do
  permissions <- ask
  if hasPermission "admin" permissions
    then map Just newUser
    else pure Nothing
Run Code Online (Sandbox Code Playgroud)

对我来说令人困惑的部分是ask功能.签名是:

ask   :: forall r. Reader r r
Run Code Online (Sandbox Code Playgroud)

它看起来好像是凭空创造了一个阅读器

当我读到Statemonad时,它的get功能与概念相同.文字解释说:

状态被实现为State monad的数据构造函数隐藏的函数参数,因此没有明确的引用传递.

我猜这是关键,同样的事情发生在这里与读者,但我不明白它是如何工作的......

当上面的例子运行时runReader,提供的值如何突然出现ask?Haskell文档ask说:检索monad环境.但我的困惑是从哪里来的?我看到它的方式,一个值传递给runReader,存储在某个地方,并得到它 - 你打电话ask......但这没有任何意义.

虽然这个例子是Purescript,但我猜测任何有Haskell识字的人也能够回答,因此Haskell标签.

monads haskell state-monad reader-monad purescript

11
推荐指数
1
解决办法
790
查看次数

有monad更优雅代码的提示?

我终于掌握了如何使用monads(不知道我是否理解它们......),但我的代码从来都不是很优雅.我想是因为缺乏对所有这些功能如何Control.Monad真正起作用的把握.所以我认为在使用状态monad的特定代码段中询问关于此的提示会很好.

代码的目标是计算多种随机游走,这是我在更复杂的事情之前尝试做的事情.问题是我同时有两个有状态计算,我想知道如何用优雅组合它们:

  1. 更新随机数生成器的函数是类型的 Seed -> (DeltaPosition, Seed)
  2. 更新随机游走者位置的功能属于某种类型DeltaPosition -> Position -> (Log, Position)(Log我只能通过某种方式报告随机游走者的当前位置).

我做的是这样的:

我有一个函数来组成这两个有状态的计算:

composing :: (g -> (b, g)) -> (b -> s -> (v,s)) -> (s,g) -> (v, (s, g))
composing generate update (st1, gen1) = let (rnd, gen2) = generate gen1
                                            (val, st2)  = update rnd st1
                                        in (val, (st2, gen2))
Run Code Online (Sandbox Code Playgroud)

然后我把它变成一个组成状态的函数:

stateComposed :: State g b -> (b -> State s v) -> State (s,g) v
stateComposed rndmizer updater …
Run Code Online (Sandbox Code Playgroud)

monads haskell state-monad monad-transformers

10
推荐指数
1
解决办法
1048
查看次数

在Haskell中组合monad

我正在尝试将Spider Solitaire播放器编写为Haskell学习练习.

我的main函数将为playGame每个游戏(使用mapM)调用一次函数,传入游戏编号和随机生成器(StdGen).该playGame函数应该返回一个Control.Monad.Statemonad和一个IO monad,其中包含一个String显示游戏画面并Bool指示游戏是赢还是输的.

如何将Statemonad与IOmonad 结合起来获得返回值?`playGame的类型声明应该是什么?

playGame :: Int -> StdGen a -> State IO (String, Bool)
Run Code Online (Sandbox Code Playgroud)

是对的State IO (String, Bool)吗?如果不是,它应该是什么?

main,我计划使用

do
  -- get the number of games from the command line (already written)
  results <- mapM (\game -> playGame game getStdGen) [1..numberOfGames]
Run Code Online (Sandbox Code Playgroud)

这是正确的打电话playGame吗?

io haskell state-monad

10
推荐指数
2
解决办法
2161
查看次数

在这种情况下,为什么在与嵌套的StateT monadT交互时不需要使用'lift'?

假设我有一个monadT:

type Wrap a = ReaderT Env ( StateT Int ( StateT Int Identity ) ) a
Run Code Online (Sandbox Code Playgroud)

这里要注意的重要一点是,一个StateT正在包装另一个,并且两者都包含在第三个MonadT内,即ReaderT.

以及相应的runWrap函数以方便:

type Env = Map.Map Char Integer

runWrap :: Env -> Int -> Int -> Wrap a -> a
runWrap env st1 st2 m = runIdentity $ evalStateT ( evalStateT ( runReaderT m env ) st2 ) st1
Run Code Online (Sandbox Code Playgroud)

一个通用的tock状态monad:

tock :: (Num s, MonadState s m) => m ()
tock = do modify (+1)
Run Code Online (Sandbox Code Playgroud)

我现在创建一个包裹monadT,其中我使用tock:

aWrap :: Wrap ( Int, Int ) …
Run Code Online (Sandbox Code Playgroud)

monads haskell state-monad monad-transformers

10
推荐指数
1
解决办法
429
查看次数

为什么我们必须使用状态monad而不是直接传递状态?

有人可以展示一个简单的例子,其中状态monad可以比直接传递状态更好吗?

bar1 (Foo x) = Foo (x + 1)
Run Code Online (Sandbox Code Playgroud)

VS

bar2 :: State Foo Foo
bar2 = do
  modify (\(Foo x) -> Foo (x + 1))
  get
Run Code Online (Sandbox Code Playgroud)

monads haskell state-monad purely-functional

10
推荐指数
2
解决办法
1813
查看次数