超载+ F# 中的运算符
所以我有这个:
open System
open System.Linq
open Microsoft.FSharp.Collections
type Microsoft.FSharp.Collections.List<'a> with
static member (+) (First : List<'a>) (Second : List<'a>) =
First.Concat(Second)
let a = [1; 2; 3; 4; 54; 9]
let b = [3; 5; 6; 4; 54]
for x in List.(+) a b do
Console.WriteLine(x)
我想将最后一行转换为,
for x in a + b do
Console.WriteLine(x)
但这样做给了我一个
The type 'int list' does not support any operands named '+'
网络上的文档和示例很脆弱,尽管我用谷歌搜索,但我一直无法让它工作。基本上,来自 python 背景,我希望我的列表操作语法像我习惯的那样简洁:它不应该需要超过 1 个中缀表示法的字符。
So i have this:
open System
open System.Linq
open Microsoft.FSharp.Collections
type Microsoft.FSharp.Collections.List<'a> with
static member (+) (First : List<'a>) (Second : List<'a>) =
First.Concat(Second)
let a = [1; 2; 3; 4; 54; 9]
let b = [3; 5; 6; 4; 54]
for x in List.(+) a b do
Console.WriteLine(x)
and I want to convert the last line into
for x in a + b do
Console.WriteLine(x)
but doing so gives me a
The type 'int list' does not support any operands named '+'
The documentation and examples on the web are flakey, and despite my google-fu i have been unable to get it to work. Basically, coming from a python background, I want to get my list manipulation syntax as terse as I am used to: it should not need more than 1 character in infix notation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先,重写运算符应该以元组形式声明,而不是以进位形式声明。在您的情况下:
其次,修复该问题后,编译器会引发“扩展成员无法提供运算符重载。请考虑将运算符定义为类型定义的一部分。” 警告。 F# 中的重载运算符:(/) 中已详细讨论了一些解决方法。
First, overriding operators should be declared in the tuple form, not in the carried form. In your case:
Second, after you fix that, the compiler raises the
"Extension members cannot provide operator overloads. Consider defining the operator as part of the type definition instead."
warning. There are some workarounds which have been discussed thoroughly in Overload operator in F#: (/).请注意,
@
已经是用于连接列表的 1 字符中缀运算符。Note that
@
is already a 1-char infix operator to concat lists.实际上,有一种方法可以使用静态约束和重载来“重新连接”现有运算符。
通过使用三元运算符,将自动推断静态约束,另一种选择是创建一个方法并手动编写约束。
第一个重载涵盖您要添加的情况(列表),第二个重载涵盖现有定义。
所以现在在您的代码中您可以执行以下操作:
这不会破坏数字类型的现有
(+)
。Actually there is a way to 're-wire' existing operators, using static constraints and overloads.
By using the ternary operator the static constraints will be automatically inferred, another option would be to create a method and write the constraints by hand.
The first overload cover the case you want to add (lists), the second covers the existing definition.
So now in your code you can do:
And that will not break existing
(+)
for numeric types.正如其他答案所指出的,您无法将
+
的实现添加到现有类型,因为扩展成员被忽略,并且独立的let
绑定隐藏了默认(重载)实现。如果您想使用
+
(实际上并不需要,因为 F# 库包含运算符@
),您必须为直接支持该运算符的 F# 列表编写包装器:As pointed out by the other answers, you cannot add implementation of
+
to an existing type, because extension members are ignored and standalonelet
binding hides the default (overloaded) implementation.If you wanted to use
+
(which is not really needed because F# library contains operator@
), you would have to write wrapper for F# list that supports the operator directly:我认为使用扩展方法的运算符重载不起作用。您可以做的是使用以下命令为列表 (+) 定义全局运算符重载:
I think operator overloading using extension method doesn't work. What you can do is define a global operator overload for list (+) using: