Search code examples
asynchronousf#pipeline

Is this async pipelining operator ok


What if we define a |>! operator like so:

let (|>!) a f = async {
    let! r = a
    return f r
} 

Then instead of writing

let! r = fetchAsync()
work r

we could write

fetchAsync() |>! work

Is this a good idea or would it generate inefficient code?


Solution

  • The |>! operator you're describing is the standard "map" pattern that can apply to just about any "wrapper" type, not just async. If your return f r had been return! f r then you would have the standard "bind" pattern, which by convention should be written as the operator >>= if you're defining an operator for it.

    And it is a good idea, but with one minor change. You've written it with the async value as the first parameter and the function as the second parameter, but the way you used it, fetchAsync() |>! work, requires the function to be the first parameter, e.g. let (|>!) f a = .... (If you look at the way Scott Wlaschin implements this in the first example I linked, he puts the function as the first parameter as well.) Also, I think most F# programmers would choose not to write this as an operator, but as a function called Async.map, so that its usage would look like this:

    let result =
        fetchAsync()
        |> Async.map step1
        |> Async.map step2
        |> Async.map step3