5

我是不是很傻?有些东西在 monad/computation 表达式中看起来更好,我有很多使用 seq 计算表达式的代码,但是每次我点击一个选项<>我都必须恢复到“Option.map”等。

有点刺耳(当我在 C# 中执行此操作时,我为 IMaybe<> 类型编写了一个 linq 运算符,这一切看起来都很好且一致)。

我可以,但不是特别想写一个,肯定有一个(或多个),人们使用哪一个?

IE

所以而不是

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

我们可以去

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

我对前一个代码没有任何问题,除了在我的上下文中它存在于许多看起来像后者的“seq”计算表达式中(并且一些将查看此代码的开发人员将来自 C#/LINQ 背景,基本上是后者)。

4

2 回答 2

4

FSharp.Core中没有optionCE,但它存在于某些库中。

我认为 FSharp.Core 中没有提供许多 CE 的原因之一是因为有很多不同的方法来做它们,如果你用谷歌搜索选项计算表达式构建器,你会发现有些是严格的,有些是懒惰的,有些是支持方面-影响其他人支持将多个返回值混合为一个。

关于库,在F#x中有一个称为maybe然后你有F#+,它提供通用计算表达式,所以你有类似 Linq 的东西,只要类型实现 CE 准备使用的一些方法,你可以使用let x:option<_> = monad' { ... let x:option<_> = monad.plus' { ... 如果您更喜欢允许多个返回值的那个。

您的代码将如下所示:

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

您的选项生成器在哪里option,可能是上述之一。

于 2020-10-09T13:38:28.380 回答
3

我们使用 FsToolkit.ErrorHandling。它简单、积极维护并且运行良好。

它具有选项、结果、结果选项、验证、AsyncResult、AsyncResultOption 的 CE。

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

于 2020-10-09T14:39:26.803 回答