【发布时间】:2015-07-10 16:41:55
【问题描述】:
我正试图围绕 F# 中的 mon-、err、工作流,虽然我认为我对基本的“可能”工作流有相当扎实的理解,但尝试实现一个状态工作流来生成随机数已经真的把我难住了。
我的未完成尝试可以在这里看到:
let randomInt state =
let random = System.Random(state)
// Generate random number and a new state as well
random.Next(0,1000), random.Next()
type RandomWF (initState) =
member this.Bind(rnd,rest) =
let value, newState = rnd initState
// How to feed "newState" into "rest"??
value |> rest
member this.Return a = a // Should I maybe feed "initState" into the computation here?
RandomWF(0) {
let! a = randomInt
let! b = randomInt
let! c = randomInt
return [a; b; c]
} |> printfn "%A"
编辑:实际上让它工作了!虽然不完全确定它是如何工作的,所以如果有人想把它放在一个好的答案中,它仍然可以争夺。这是我的工作代码:
type RandomWF (initState) =
member this.Bind(rnd,rest) =
fun state ->
let value, nextState = rnd state
rest value nextState
member this.Return a = fun _ -> a
member this.Run x = x initState
【问题讨论】:
-
你有什么问题?
-
如何解决?或者一般应该如何构建这样的 monad/工作流。
-
这里很好地描述了 state monad 是如何工作的。它有点冗长(3 部分),但值得一读。也许它会帮助fsharpforfunandprofit.com/posts/monadster
-
啊,我喜欢 fsharpforfunandprofit!实际上,在编写此代码时,我一直在研究这个系列:fsharpforfunandprofit.com/posts/computation-expressions-intro。感谢您的链接!
-
通过使用生成的数字播种下一个随机数,您可能会陷入循环。 IE。 Random(123).Next(0,1000).Next() == 123。如果能从 Random 中获取种子就好了,但它没有暴露。最好的选择是滚动你自己的 Random 类,或者使用 Random 是可序列化的事实并将其序列化并将该字符串传出和传入。
标签: f# state monads state-monad