gpt4 book ai didi

f# - 在 F# 中扩展 Core.Option 模块

转载 作者:行者123 更新时间:2023-12-04 13:27:53 24 4
gpt4 key购买 nike

我想扩展现有的“核心”模块之一,例如 Core.Option :

module Microsoft.FSharp.Core.Option

let filter predicate op =
match op with
| Some(v) -> if predicate(v) then Some(v) else None
| None -> None

(我知道 bind 函数,但我认为 filter 在某些情况下用于选项的方法更方便)。

但不幸的是我不能使用 filter没有明确打开的方法 Microsoft.FSharp.Core命名空间:
// Commenting following line will break the code!
open Microsoft.FSharp.Core

let v1 = Some 42
let v2 = v1 |> Option.filter (fun v -> v > 40)

printfn "v2 is: %A" v2

在大多数情况下,如果不打开适当的命名空间,我们就无法使用模块中的函数。
F# 编译器自动“打开”一些预定义(核心)命名空间(如 Microsoft.FSharp.Core),这不会将“模块扩展”中的方法引入范围,我们仍然应该手动打开核心命名空间。

我的问题是:有什么解决方法吗?

或者扩展“核心”模块的最好方法是在自定义命名空间中创建这样的扩展并手动打开这个命名空间?
// Lets custom Option module in our custom namespace
module CustomNamespace.Option

let filter predicate op = ...

// On the client side lets open our custom namespace.
// After that we can use both Option modules simultaneously!
open CustomNamespace

let v1 = Some 42
let b =
v1 |> Option.filter (fun v -> v > 40) // using CustomNamespace.Option
|> Option.isSome // using Microsoft.FSharp.Core.Option

最佳答案

对于生产代码,我会按照 Taha 的回答建议:创建自己的模块并根据需要打开/为其设置别名。作为程序员,你一生的大部分时间都花在阅读代码上。在不清楚方法来自何处的 F# 代码中,阅读 F# 代码可能会非常令人沮丧。

话虽如此,我惊讶地发现这有效:

namespace Microsoft.FSharp.Core

module Option =

let filter predicate op =
match op with
| Some(v) -> if predicate(v) then Some(v) else None
| None -> None

namespace USERCODE

module Option = Microsoft.FSharp.Core.Option

module M =

let test () =
Some 1
|> Option.filter (fun x -> x > 0)
|> Option.map (fun x -> x + 1)

它并没有消除在文件头部写入内容的需要,但它确实解决了需要打开命名空间的问题。与 Microsoft.FSharp.Core 无关因为默认情况下它总是打开的,但对其他命名空间很有帮助。

关于f# - 在 F# 中扩展 Core.Option 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16078213/

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