【问题标题】:is there an option<> computation expression anywhere?任何地方都有 option<> 计算表达式吗?
【发布时间】:2020-10-09 09:22:18
【问题描述】:

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

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

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

所以而不是

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 背景基本上是后者)。

【问题讨论】:

  • 如果您可以分享一段特定的代码,也许会更容易理解您要问的问题是什么。
  • 我已经修改了问题

标签: f#


【解决方案1】:

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

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

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

您的代码将如下所示:

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-05
      • 2014-04-30
      • 1970-01-01
      相关资源
      最近更新 更多