gpt4 book ai didi

f# - 为自定义集合定义 cons (::) 运算符

转载 作者:行者123 更新时间:2023-12-03 21:56:22 24 4
gpt4 key购买 nike

我正在使用相当流行的 FSharpx.Collections包,尤其是 NonEmptyList类型。

此类型提供 NonEmptyList.cons函数,但我想使用 ::运算符与常规 List 一样,即 head :: tail .自 tail必须已经是 NonEmptyList<'a> , 应该与 List 没有任何冲突的 ::运算符(operator)。

但是,似乎我无法定义运算符。这个:

let ( :: ) h t = NonEmptyList.cons h t

导致编译错误:
Unexpected symbol '::' in pattern. Expected ')' or other token.

我知道 ::与其他运营商不在同一类别中,但我不完全了解如何。所以我或多或少地随机尝试了一些东西,比如替换 ::op_cons之类的,没有成功。

我错过了什么,有没有办法做我想做的事?

最佳答案

According to MSDN , 冒号实际上不能用于运算符名称。这似乎与 the F# specification 矛盾来自 FSharp.org,我不确定那里发生了什么。但我们可以在 FSI 中验证:

> let ( >:> ) a b = a+b
Script.fsx(1,7): error FS0035: This construct is deprecated: ':' is not permitted as a character in operator names and is reserved for future use

如果你看 how List<'T> is defined ,你会发现 (::)实际上不是运算符,而是 case 构造函数:
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list

果然,你可以用它定义你自己的 DU 类型作为构造函数名称:
> type A = 
> | ( :: ) of string * int
> | A of int
>
> let a = "abc" :: 5

val a : A = Cons ("abc",5)

现在,奇怪的是,如果我尝试使用另一个类似操作符的名称作为 case 构造函数,我会收到此错误:
> type A = | ( |> ) of string * int
Script.fsx(1,14): error FS0053: Discriminated union cases and exception labels must be uppercase identifiers

这意味着 (::)有点特别(顺便说一下, ([]) 也是如此)。

所以底线似乎是 - 不,你不能那样做。
但为什么你甚至需要?也许你能接受一个更容易接受的操作符名称,它仍然可以表达“缺点”的语义——比如, (<+>) ?

关于f# - 为自定义集合定义 cons (::) 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32297544/

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