gpt4 book ai didi

f# - 避免嵌套模式匹配(可能与monad)

转载 作者:行者123 更新时间:2023-12-04 03:09:52 24 4
gpt4 key购买 nike

如何重写嵌套模式匹配,例如以下示例,以便 None只指定一次?我认为 Maybe monad 解决了这个问题。 F# 核心库中是否有类似的东西?或者,有没有替代方法?

match a with
| Some b ->
let c = b.SomeProperty
match c with
| Some d ->
let e = d.SomeProperty
//and so on...
| None -> ()
| None -> ()

最佳答案

您可以使用内置功能解决此问题: Option.bind

type A = 
member this.X : B option = Unchecked.defaultof<_>
and B =
member this.Y : С option = Unchecked.defaultof<_>
and С =
member this.Z : string option = Unchecked.defaultof<_>


let a : A = Unchecked.defaultof<_>
let v =
match
a.X
|> Option.bind (fun v -> v.Y)
|> Option.bind (fun v -> v.Z) with
| Some s -> s
| None -> "<none>"

坦率地说,我怀疑在这里引入成熟的“可能”实现(通过计算表达式)可以缩短代码。

编辑 :梦想模式 - 开启

我认为如果 F# 对特殊情况有更轻量级的语法,那么带有 Option.bind 的版本可以更小: lambda 引用其参数的某个成员:
"123" |> fun s -> s.Length // current version
"123" |> #.Length // hypothetical syntax

这就是如何在已经具有此类功能的 Nemerle 中重写示例:
using System;
using Nemerle.Utility; // for Accessor macro : generates property for given field

variant Option[T]
{
| Some {value : T}
| None
}

module OptionExtensions
{
public Bind[T, U](this o : Option[T], f : T -> Option[U]) : Option[U]
{
match(o)
{
| Option.Some(value) => f(value)
| Option.None => Option.None()
}
}
}

[Record] // Record macro: checks existing fields and creates constructor for its initialization
class A
{
[Accessor]
value : Option[A];
}

def print(_)
{
// shortened syntax for functions with body -> match over arguments
| Option.Some(_) => Console.WriteLine("value");
| Option.None => Console.WriteLine("none");
}

def x = A(Option.Some(A(Option.Some(A(Option.None())))));
print(x.Value.Bind(_.Value)); // "value"
print(x.Value.Bind(_.Value).Bind(_.Value)); // "none"

关于f# - 避免嵌套模式匹配(可能与monad),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4073161/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com