geoff_h
geoff_h

Reputation: 1253

F# : Monad operations without computation expressions

Does F# provide any "standard" set of operators for dealing with monadic (specifically Async) operations outside of computation expressions? I'm finding my code ends up littered with a lot of local operator definitions like:

let (>>=) a b = async.Bind (a, b)

Given how nice the set of operators is for composing pure functions - <|, |> and >> etc - I feel I must be missing something here.

To preempt possible comments - computation expressions are fine for some things, but for pipelining a series of asynchronous operations:

async {
    let! a' = a
    let! b' = b a'
    return! c b'
}

Doesn't feel as nice as:

a >>= b >>= c

Upvotes: 5

Views: 315

Answers (1)

scrwtp
scrwtp

Reputation: 13577

There's nothing of that sort available in F# core libs.

I would say those operators are an acquired taste. Not everyone comes into F# from Haskell, and for those of us who don't, this kind of code might not really read as "nice".

What works for me is having "pipeline-friendly" versions of those operations around, as a sort of middle ground between workflows and inline operators:

module Async = 
    let bind f a = async.Bind (a, f)

Which gives you enough rope to work with monadic types outside workflows while still using the standard set of function composition operators:

a
|> Async.bind b
|> Async.bind c  

For a more Haskell-like experience in F#, FSharpPlus might be what you're looking for.

Upvotes: 12

Related Questions