gpt4 book ai didi

Scalaz - 结合 List 和 State Monad 进行理解

转载 作者:行者123 更新时间:2023-12-04 11:27:10 27 4
gpt4 key购买 nike

我计划开始在我的 Scala 代码中使用 Monadic 样式来处理线程状态等。这是一个结合 3 个单子(monad)函数的简化示例(并且只关心副作用)

import scalaz._
import Scalaz._

object MonadTest {
def adder(i: Int) = State[String, Int] ({str: String => (str + i.toString + " ", i) })
val oneTwoThreeMonad = for {
m1 <- adder(1)
m2 <- adder(2)
m3 <- adder(3)
} yield m3
oneTwoThreeMonad("start: ")._1 //String = "start: 1 2 3 "
}

这一切都是不言自明的,并且按预期工作。但是为了让这种方法对我真正有用,我希望能够将它与 List 结合使用。为了理解。这是一些(不起作用的)代码来说明我的意思:
val list = List(1, 2, 3)

val oneTwoThreeBis = for {
i <- list
mx <- adder(i)
} yield mx

基本上我希望能够根据来自 List 的参数组合单子(monad)。 - 对 list 的每个元素运行一元函数并在我去的时候积累副作用。我理解示例语法不起作用,我明白为什么它不起作用 - 我只是在寻找一个干净、优雅的等价物。

我很确定使用 scalaz monad 转换器可以实现这一点,更具体地说是使用 StateT但我不确定如何去做。

PS。我使用的是 Scalaz 7.0-M3,因此语法可能与最常见的 6.x 略有不同。

最佳答案

我不确定我是否完全理解你在寻找什么,但听起来你想要更像 traverse 的东西这里(其中 traverse 是 Haskell 的 mapM 的更通用版本):

import scalaz._, Scalaz._

def adder(i: Int) = State[String, Int](str => (str + i.toString + " ", i))

List(1, 2, 3).traverseS(adder)("start: ")._1

这将按预期打印以下内容:
res0: String = "start: 1 2 3 "

请注意,我使用的是 traverseS (其中 S 代表 State )以避免写出相当困惑的类型参数,但是 traverse当您想将一元函数映射到可遍历的东西上时,它更普遍有用。

我很高兴给 StateT例如,如果这不是您想要的,但最终您将拥有 List[(String, Int)] 类型的东西.

关于Scalaz - 结合 List 和 State Monad 进行理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13811463/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com