I know there is the >>= operator to pipe monads, but why is there no free-standing function named bind? So that instead of x >>= f one could write x |> bind x. This is already possible with map (<!> or |>> depending on operator order).
I think the reason why it wasn't added at the beginning is because in Monads literature, the official name of the function is simply (>>=) and they call it bind (except on Scala world), same thing with applicative 's <*>, but map is a bit different in that there is not really a standard agreed operator, not even a function, since in Haskell and some other languages it's called fmap.
Having said that and now, looking from the F# world:
.bind seems to be quite standard in libraries and CEs.map as well, some projects (like this one and FParsec) use also the |>> operator, while <!> seems to have a wider adoption, although it's semantics are more tied to Applicatives that Functors..apply seems to be used frequently for <*>So, I think your question reveals a valid discussion, could you summarize what would be the main benefit of having a generic bind available, in place of just using (=<<) ?
More readable for non-FP-heads, and lower "WTF factor" when finding out the standard and expected bind function doesn't exist. :)
In the case when you'd browse the API using intellisense, it does makes sense to have bind defined. However, in parts of the library, Identity.fs#L18 they are defined differently than you'd expect from a bind (they are static members in order for this to work). You could expose the functions with f# signature in modules.
There's a lot of "trickery" in this library that I don't understand, but isn't bind defined this as easy shown below?
f#
let inline bind = (=<<)
I think I misunderstood what it was you wanted. Then it sounds like something that could be implemented in a single pull request, see for instance:
https://github.com/fsprojects/FSharpPlus/blob/v1.0.0/src/FSharpPlus/Operators.fs#L72-L76
i.e. you would get
f#
/// Takes a function from a plain type to a monadic value and a monadic value, and returns a new monadic value.
let inline bind (f:'T->'``Monad<'U>``) (x:'``Monad<'T>``) :'``Monad<'U>`` = Bind.Invoke x f
Great! To be clear, I'm after this usage (lame example, but I hope the usage is clear):
f#
Some 2
|> map Some
|> bind id
// we're back to Some 2
isn't that join ?
bind id is join yes, but I'm after bind in itself and that degenerate example was the first that came to mind.
Here's another:
```f#
type Person = { Name: string option }
tryGetPerson ()
|> bind (fun p -> p.Name)
```
I'm sort of in favor of it, since it allows you to use the generic version with the explicit name. Perhaps @cannorin has any insights?
I don't see why it should not be in the library. Since the library already has map as a generic alternative to Option.map, List.map etc., it should also have bind as an alternative to Option.bind etc. :)
Personally I don't need it but I don't see any downside of adding it to F#+.
Same comment as @cannorin and yes, the definition is basically that, but you need to add explicit parameters as values cannot be inlines.
So, if everybody agrees, feel free to PR
Already did #194
Just quick and dirty, feel free to improve or discard, I've no need to own this change
Most helpful comment
Personally I don't need it but I don't see any downside of adding it to F#+.