Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is there an option<> computation expression anywhere?

Tags:

f#

Am I being stupid? Some things look nicer in a monad/computation expression, I have lots of code using the seq computation expression, but everytime I hit an option<> I have to revert to "Option.map" etc.

Slightly jarring (when I was doing this in C# I wrote a linq operator for a IMaybe<> type and it all looked nice and consistent).

I can, but don't especially want to write one, there must be one (or more) out there, which one do people use?

i.e.

so rather than

let postCodeMaybe = 
    personMaybe 
    |> Option.bind (fun p -> p.AddressMaybe())
    |> Option.map (fun -> p.Postcode())

we can go

let postCodeMaybe = 
    option {
        for p in personMaybe do
            for a in p.AddressMaybe() do
                 a.Postcode()
    }

I have no problem with the former code, except that in my context it exists in lots of "seq" computational expressions that look like the latter (and some developers who will look at this code will come from a C#/LINQ background which are basically the latter).

like image 454
MrD at KookerellaLtd Avatar asked Oct 09 '20 09:10

MrD at KookerellaLtd


Video Answer


2 Answers

There is no option CE in FSharp.Core but it exists in some libraries.

I think one of the reasons why many CEs are not provided in FSharp.Core is because there are many different ways of doing them, if you google for an option computation expression builder you'll find some are strict, others lazy, some support side-effects others support blending multiple return values into one.

Regarding libraries, there is one in F#x called maybe then you have F#+ which provides generic computation expressions so you have something like Linq where as long as the type implement some methods the CE is ready to use, for options you can use let x:option<_> = monad' { ... or let x:option<_> = monad.plus' { ... if you prefer to have the one that allows multiple return values.

Your code will look like:

let x: option<_> = option {
   let! p = personMaybe
   let! a = p.AddressMaybe()
   return a }

Where option is your option builder, could be one of the above mentioned.

like image 184
Gus Avatar answered Oct 07 '22 12:10

Gus


We use FsToolkit.ErrorHandling. It is simple, actively maintained and works well.

It has CEs for Option, Result, ResultOption, Validation, AsyncResult, AsyncResultOption.

https://www.nuget.org/packages/FsToolkit.ErrorHandling/ https://github.com/demystifyfp/FsToolkit.ErrorHandling

like image 34
Roland Andrag Avatar answered Oct 07 '22 14:10

Roland Andrag