标签: state-monad

State,ST,IORef和MVar之间的区别

我正在通过48小时为自己编写一个方案(我大约85小时)而且我已经完成了关于添加变量和赋值的部分.本章中有一个很大的概念性跳跃,我希望它分两步完成,两者之间有很好的重构,而不是直接跳到最终的解决方案.无论如何…

我已经得到了一些不同类的,似乎达到相同的目的失去了:State,ST,IORef,和MVar.文本中提到了前三个,而最后三个似乎是许多关于前三个问题的StackOverflow问题的最佳答案.它们似乎在连续调用之间都处于状态.

这些是什么以及它们如何彼此不同?


特别是这些句子没有意义:

相反,我们使用一个名为状态线程的功能,让Haskell为我们管理聚合状态.这使我们可以像在任何其他编程语言中一样处理可变变量,使用函数来获取或设置变量.

IORef模块允许您在IO monad中使用有状态变量.

所有这一切都使这条线路type ENV = IORef [(String, IORef LispVal)]混乱 - 为什么第二个IORef呢?如果我写的话会破坏什么type ENV = State [(String, LispVal)]

variables monads haskell state-monad ioref

87
推荐指数
3
解决办法
1万
查看次数

斯卡拉兹州的monad例子

我没见过很多scalaz state monad的例子.有这个例子,但很难理解,似乎只有一个关于堆栈溢出的问题.

我将发布一些我玩过的例子,但我会欢迎其他的例子.此外,如果有人可以提供上的例子,为什么init,modify,putgets用于将是巨大的.

编辑:是一个关于州monad的令人敬畏的2小时演讲.

scala state-monad scalaz

76
推荐指数
3
解决办法
1万
查看次数

使用Haskell状态monad一个代码味?

上帝我讨厌"代码味"这个词,但我想不出更准确的东西.

我正在业余时间为Whitespace设计一个高级语言和编译器,以了解编译器构造,语言设计和函数编程(编译器是用Haskell编写的).

在编译器的代码生成阶段,我必须在遍历语法树时保持"状态" - 数据.例如,在编译流控制语句时,我需要为要跳转到的标签生成唯一的名称(从传入,更新和返回的计数器生成的标签,并且绝不能再次使用计数器的旧值).另一个例子是当我在语法树中遇到内联字符串文字时,它们需要永久转换为堆变量(在空白中,字符串最好存储在堆上).我目前正在处理状态monad中的整个代码生成模块来处理这个问题.

我被告知编写编译器是一个非常适合功能范例的问题,但我发现我的设计方式与我在C中设计它的方式大致相同(你真的可以用任何语言编写C语言 - 甚至Haskell w/state monads).

我想学习如何在Haskell中思考(而不是在函数范式中) - 而不是在C中使用Haskell语法.我真的应该尝试消除/最小化状态monad的使用,还是一个合法的功能"设计模式"?

monads haskell coding-style state-monad

57
推荐指数
3
解决办法
1万
查看次数

ST Monad ==代码味道?

我正在努力在Haskell中实现UCT算法,这需要大量的数据杂耍.没有太多细节,它是一个模拟算法,在每个"步骤",基于一些统计属性选择搜索树中的叶节点,在该叶子上构造新的子节点,并且对应于新叶及其所有祖先都会更新.

鉴于所有这些杂耍,我并不是非常敏锐,无法弄清楚如何使整个搜索树成为Okasaki的一个不可改变的数据结构.相反,我一直在玩STmonad,创建由可变STRefs 组成的结构.一个人为的例子(与UCT无关):

import Control.Monad
import Control.Monad.ST
import Data.STRef

data STRefPair s a b = STRefPair { left :: STRef s a, right :: STRef s b }

mkStRefPair :: a -> b -> ST s (STRefPair s a b)
mkStRefPair a b = do
    a' <- newSTRef a
    b' <- newSTRef b
    return $ STRefPair a' b'

derp :: (Num a, Num b) => STRefPair s a b -> ST s …
Run Code Online (Sandbox Code Playgroud)

monads state haskell state-monad

45
推荐指数
3
解决办法
7407
查看次数

关于"了解你的Haskell"的State Monad代码的困惑

我正在尝试使用在线书籍了解Haskell以获得很好的Haskell.

据我所知,到目前为止,我已经能够理解Monads,直到我介绍State Monad这一章.

然而,代码呈现并声称是Monad实现的State类型(我无法在Hoogle中找到它)对我来说似乎太过分了.

  • 首先,我不理解它背后的逻辑,即为什么它应该工作以及作者如何考虑这种技术.(可能会建议相关的文章或白皮书?)

  • 在第4行,建议函数f取1个参数.
    然而,几行下来我们会看到pop,它没有参数!

  • 为了扩展第1点,作者试图使用函数来表示状态.

非常感谢任何帮助理解正在发生的事情.

编辑

敬启者,

以下答案彻底涵盖了我的问题.
我想补充一点:

在阅读了下面提到的文章之后,我找到了上面第二点的答案:所有那段时间我都假设 pop函数会被用作:
stuff >>= pop因为在bind类型中第二个参数是函数,而正确的用法是这样的pop >>= stuff,我在再次阅读之后意识到,如何将符号转化为简单的绑定 - lambdas.

monads haskell state-monad

22
推荐指数
4
解决办法
4063
查看次数

对 Haskell 中 Do 语句中的箭头感到困惑

我正在努力理解Statemonad,并编写了著名的斐波那契数列的两个简单版本来记忆该函数。let体内的那只跑的很慢。那个<-跑得很快。我的问题:为什么?<-在允许M.lookup通孔Data.Map工作的同时,是否让以某种方式引起全面评估?

-- using state monad and let

-- very slow

fibLet :: Int -> State (M.Map Int Integer) Integer
fibLet n = do
   case n of 0 -> return 0
             1 -> return 1
             n -> do 
                  mp <- get
                  if M.member n mp 
                  then return $ fromJust (M.lookup n mp)
                  else do
                       let s1 = evalState (fibLet (n - 1)) mp                        
                       let s2 = evalState (fibLet (n …
Run Code Online (Sandbox Code Playgroud)

monads haskell memoization state-monad

21
推荐指数
1
解决办法
928
查看次数

在scalaz中分层状态

将状态与Either进行整合(幻灯片88)时,给定State分层下的模式Either,是否有建议的方法来添加另一种类型的状态,例如,通过类似的方式记录Writer?看来新的国家有现有之间的生活StateEither为了利用快速失败行为EitherflatMap.

下面是演示代码的可运行示例,调整为使用Scalaz 7.2.8在2.11.8上工作.有没有一种方法可以在现有行为的基础上干净地添加新的monad变换器,简化了重构?在Scalaz中堆叠StateT适用于堆叠,但不处理由故障快速flatMap行为创建的排序问题Either.

// Based on slide 88+ in https://speakerdeck.com/mpilquist/scalaz-state-monad
// Adjusted for Scala 2.11 (invariant A), Scalaz 7.2 (Pointed->Applicative) and Throwable on lhs of Either
object IntegratingStateAndEither {
  import scalaz._
  import scalaz.Scalaz._
  import EitherT._
  import scalaz.StateT.stateMonad

  type QueryStateS[A] = State[QueryState, A]
  type ET[F[_], A] = EitherT[F, Throwable, A]
  type QueryStateES[A] = ET[QueryStateS, A]

  object QueryStateES …
Run Code Online (Sandbox Code Playgroud)

scala state-monad monad-transformers either scalaz

20
推荐指数
1
解决办法
425
查看次数

作家Monad是否与State Monad有效?

有一个伟大的教程在这里,这似乎暗示,我认为作家单子基本上是做代表的工作的特殊情况,元组对象(A,B).作者在左边积累了值(即A),并且A与它有相应的Monoid(因此它可以累积或改变状态).如果A是一个集合,那么它就会累积.

State Monad也是一个处理内部元组的对象.它们都可以是flatMap'd,map'd等等.这些操作对我来说都是一样的.他们有什么不同?(请用scala示例回复,我不熟悉Haskel).谢谢!

monads scala state-monad scalaz writer-monad

19
推荐指数
1
解决办法
1649
查看次数

如何只更新几个时,如何避免引用所有状态变量?

我用来编写几个程序(带内存)的习语如下:

p1 :: State (Int, String) ()
p1 = do
    (a, b) <- get
    ... do something ...
    put (a', b)

p2 :: State (Int, String) ()
p2 = do
    (a, b) <- get
    ... do something else ...
    put (a, b')

main = do
    ... initializing a0 b0 ...
    print . flip evalState (a0, b0)
          . sequence $ replicate 10 p1 ++ repeat p2
Run Code Online (Sandbox Code Playgroud)

但是,随着状态变量数量的增加,这很快就会变得比必要的更冗长:

p1 :: State (Int, String, Bool, Int, String, Bool) ()
p1 = do
    (a, …
Run Code Online (Sandbox Code Playgroud)

haskell state-monad

19
推荐指数
3
解决办法
562
查看次数

State Monad,随机数序列和monadic代码

我正在努力掌握State Monad并且为了这个目的,我想编写一个使用线性同余生成器生成一系列随机数的monadic代码(可能不好,但我的目的只是学习State Monad,而不是建立一个好的RNG库).

生成器就是这样(Bool为了简单起见,我想生成一系列s):

type Seed = Int

random :: Seed -> (Bool, Seed)
random seed = let (a, c, m) = (1664525, 1013904223, 2^32)  -- some params for the LCG
                  seed' = (a*seed + c) `mod` m
              in  (even seed', seed')   -- return True/False if seed' is even/odd 
Run Code Online (Sandbox Code Playgroud)

不要担心数字,这只是种子的更新规则(根据Numerical Recipes)应该生成Ints 的伪随机序列.现在,如果我想按顺序生成随机数,我会这样做:

rand3Bools :: Seed -> ([Bool], Seed)
rand3Bools seed0  = let (b1, seed1) = random seed0
                        (b2, seed2) = random seed1
                        (b3, seed3) = random …
Run Code Online (Sandbox Code Playgroud)

monads haskell state-monad do-notation

17
推荐指数
3
解决办法
2454
查看次数