我正在使用一个表示float * float
之类的点的API。
这些不方便对以下内容进行算术运算:
let a = (3.0, 4.0)
let b = (2.0, 1.0)
let c = (fst a + fst b, snd a + snd b)
我想写:
let c = a + b
如果我定义自己的类型,我可以这样做:
type Vector2 =
{
X : float;
Y : float;
}
with
static member (+) (a : Vector2, b : Vector2) =
{ X = a.X + b.X; Y = a.Y + b.Y }
但是随后我需要转换为我正在使用的API:
let c = a + b
let cAsTuple = (c.X, c.Y)
或者,我可以创建一个自由函数:
let add (ax, ay) (bx, by) =
(ax + bx, ay + by)
let c = a |> add b
但这并不像真正的中缀运算符那么好。
F#是否允许我为元组定义自定义运算符?
答案 0 :(得分:7)
如果您愿意使用(+.)
之类的其他运算符,则可以执行以下操作:
let inline (+.) (a,b) (c,d) = (a + c, b + d)
它适用于整数,浮点数和字符串:
( 4 , 3 ) +. ( 3 , 2 ) // (7, 5)
( 4., 3.) +. ( 3., 2.) // (7.0, 5.0)
("4", "3") +. ("3", "2") // ("43", "32")
答案 1 :(得分:6)
TL; DR; @AMieres的答案是真实的,这应该是注释,但注释的长度有限且代码格式不好__(ツ)_ /¯
使操作员扩展成为现实的工作正在进行中:Issue,RFC,PR一旦完成,以下操作可能终于起作用:
open System
open System.Runtime.CompilerServices
[<Extension>]
type TupleExtensions() =
[<Extension>]
static member inline (+) ((x1, y1), (x2, y2)) = (x1 + x2, y1 + y2)
// or
type Tuple<'T1, 'T2> with
// warning FS1215: Extension members cannot provide operator overloads.
// Consider defining the operator as part of the type definition instead.
static member inline (+) ((x1, y1), (x2, y2)) = (x1 + x2, y1 + y2)
// and then
let t1 = (1., 2.)
let t2 = (42., 3.141)
TupleExtensions.(+) (t1, t2) // (43.0, 5.141)
// error FS0001: Expecting a type supporting the operator '+' but given a tuple type
t1 + t2