在F#中,是否可以为元组实现运算符?

sdg*_*sdh 4 f#

我正在使用代表点的API float * float.

这些不方便做算术:

let a = (3.0, 4.0)
let b = (2.0, 1.0)

let c = (fst a + fst b, snd a + snd b)
Run Code Online (Sandbox Code Playgroud)

我想写:

let c = a + b
Run Code Online (Sandbox Code Playgroud)

如果我定义自己的类型,我可以这样做:

type Vector2 =
  {
    X : float;
    Y : float;
  }
  with
    static member (+) (a : Vector2, b : Vector2) =
      { X = a.X + b.X; Y = a.Y + b.Y }
Run Code Online (Sandbox Code Playgroud)

但后来我需要转换我正在使用的API:

let c = a + b
let cAsTuple = (c.X, c.Y)
Run Code Online (Sandbox Code Playgroud)

或者,我可以创建一个自由函数:

let add (ax, ay) (bx, by) = 
  (ax + bx, ay + by)

let c = a |> add b
Run Code Online (Sandbox Code Playgroud)

但这并不像真正的中缀运营商那么好.

F#允许我为元组定义自定义运算符吗?

AMi*_*res 7

如果您愿意使用不同的运算符(+.),则可以执行以下操作:

let inline (+.) (a,b) (c,d) = (a + c, b + d)
Run Code Online (Sandbox Code Playgroud)

它适用于整数,浮点数,字符串:

( 4 ,  3 ) +. ( 3 ,  2 ) // (7, 5)
( 4.,  3.) +. ( 3.,  2.) // (7.0, 5.0)
("4", "3") +. ("3", "2") // ("43", "32")
Run Code Online (Sandbox Code Playgroud)


Car*_*Dev 6

TL; DR; @AMieres的答案是真实的答案,它应该是注释,但注释的长度受限制并且代码格式不好__(?)_ /

使操作员扩展成为现实的工作正在进行中:IssueRFCPR一旦完成,以下操作可能终于起作用:

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
Run Code Online (Sandbox Code Playgroud)