Can I use different workflows simultaneously in F#?

前端 未结 3 1723
感动是毒
感动是毒 2021-01-25 11:19

I need my state to be passed along while being able to chain functions with the maybe workflow. Is there a way for 2 workflows to share the same context? If no, what is the way

3条回答
  •  甜味超标
    2021-01-25 11:47

    In F# you cannot easily mix different types of computation expressions as you would do in Haskell by using Monad Transformers or similar techniques. You could however build your own Monad, embedding state threading and optional values, as in:

    type StateMaybe<'T> = 
        MyState -> option<'T> * MyState
    
    // Runs the computation given an initial value and ignores the state result.
    let evalState (sm: StateMaybe<'T>) = sm >> fst
    
    // Computation expression for SateMaybe monad.
    type StateMaybeBuilder() =
        member this.Return<'T> (x: 'T) : StateMaybe<'T> = fun s -> (Some x, s)
        member this.Bind(sm: StateMaybe<'T>, f: 'T -> StateMaybe<'S>) = fun s ->
            let mx,s' = sm s
            match mx with
            | Some x    -> f x s'
            | None      -> (None, s)
    
    // Computation expression builder.
    let maybeState = new StateMaybeBuilder()
    
    // Lifts an optional value to a StateMaybe.
    let liftOption<'T> (x: Option<'T>) : StateMaybe<'T> = fun s -> (x,s)
    
    // Gets the current state.
    let get : StateMaybe = fun s -> (Some s,s)
    
    // Puts a new state.
    let put (x: MyState) : StateMaybe = fun _ -> (Some (), x)
    

    Here's an example computation:

    // Stateful computation
    let computation =
        maybeState {
            let! x = get
            let! y = liftOption (Some 10)
            do! put (x + y)
            let! x = get
            return x
        }
    
    printfn "Result: %A" (evalState computation 1)
    

    StateMaybe may be generalized further by making the type of the state component generic.

提交回复
热议问题