我正在使用F#做一个应用程序,我想知道我是否可以 a)将状态保持在State计算表达式下(使用FSharpx的实现)和 b)能够异步修改状态(处理用户的输入)。
我相信我知道如何分别处理每个问题;之一:
如何在FSharp或Haskell中同时使用状态和异步计算表达式?
答案 0 :(得分:4)
基本上有两种组合monad的方法:使用monad变换器或手工创建一个自定义monad,它结合了两个monad。
由于F#中没有本机类型,因此通常会使用后一种解决方案,但您可以使用F#+组合Async和State a-la Haskell并获得所需的计算表达式。
这是从Haskell翻译的一个例子:
#r @"FSharpPlus.dll"
open FSharpPlus
let print x = async {printfn "%A" x}
#nowarn "0025" // Incomplete pattern match, list is assumed not to be empty.
let code =
let inline io (x: Async<_>) : StateT<_,Async<_>> = liftAsync x
let pop = monad {
let! (x::xs) = get
do! put xs
return x}
monad {
let! x = pop
do! io <| print x
let! y = pop
do! io <| print y
return () }
let main = StateT.run code [1..10] >>= fun _ -> result ()
// try Async.RunSynchronously main