Li *_*oyi 5 f# operator-overloading
所以我有这个:
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)
Run Code Online (Sandbox Code Playgroud)
我想把最后一行转换成
for x in a + b do
Console.WriteLine(x)
Run Code Online (Sandbox Code Playgroud)
但这样做给了我一个
The type 'int list' does not support any operands named '+'
Run Code Online (Sandbox Code Playgroud)
网络上的文档和示例都很有趣,尽管我的google-fu仍然无法让它发挥作用.基本上,从蟒蛇背景的,我想我的列表操作语法简洁,因为我用的:它不应该需要在中间符号超过1个字符.
实际上,有一种方法可以使用静态约束和重载来"重新连接"现有的运算符.
type ListExtension = ListExtension with
static member (?<-) (ListExtension, a , b) = a @ b
static member inline (?<-) (ListExtension, a , b) = a + b
let inline (+) a b = (?<-) ListExtension a b
// test
let lst = [1;2] + [3;4]
// val lst : int list = [1; 2; 3; 4]
let sum = 1 + 2 + 3 + 4
// val sum : int = 10
Run Code Online (Sandbox Code Playgroud)
通过使用三元运算符,将自动推断静态约束,另一种选择是创建方法并手动编写约束.第一个重载覆盖了要添加的情况(列表),第二个覆盖了现有的定义.
所以现在在你的代码中你可以做到:
for x in (+) a b do
Console.WriteLine(x)
Run Code Online (Sandbox Code Playgroud)
这不会破坏(+)数字类型的存在.
首先,应以元组形式而不是带值形式声明覆盖运算符。在您的情况下:
type Microsoft.FSharp.Collections.List<'a> with
static member (+) (first: List<'a>, second: List<'a>) =
first.Concat(second)
Run Code Online (Sandbox Code Playgroud)
其次,在解决此问题之后,编译器将"Extension members cannot provide operator overloads. Consider defining the operator as part of the type definition instead."发出警告。在F#中的Overload运算符中有一些变通办法已被彻底讨论:(/)。