我打算在我的Scala代碼中開始使用Monadic風格,以用於線程狀態等。下面是合成3一元函數(僅約副作用關心)的一個簡單的例子Scalaz - 將列表和狀態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
參數單子結合 - 在每個元素的運行一元函數list
並隨着我去累積副作用。我知道示例語法不起作用,我明白爲什麼它不 - 我只是尋找一個乾淨,優雅的等價物。
我非常確定,使用斯卡拉茲單體變壓器可以實現這一點,更具體地說,與StateT
,但我真的不知道如何去做這件事。
PS。我使用的是Scalaz 7.0-M3,所以語法可能與最常見的6.x有些不同。
看起來像我在找什麼。但是這並沒有改變我將不得不學會在實踐中早晚使用狀態轉換器的事實) – nietaki
我剛剛意識到我已經閱讀了你的答案之一,其中包含了'traverse'和'traverseS'的詳細描述甚至爲此讚美你。我無法想象它是如何不跟我在一起的... – nietaki
如果有人需要做類似貓的事情而不是斯卡拉斯,請注意沒有'traverseS',但我有一個使用'traverseU'的工作示例:https://github.com/benhutchison/gesture/blob/master/core/jvm/src/test/scala/gesture/GestureProcessorSpec.scala#L34 –