В F # возможно ли реализовать операторы для кортежей? - PullRequest
0 голосов
/ 06 января 2019

Я работаю с 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)

Я хотел бы написать:

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 # определять пользовательские операторы для кортежей?

Ответы [ 2 ]

0 голосов
/ 07 января 2019

TL; DR; @ Ответ AMieres является реальным , это скорее комментарий, но комментарии ограничены по длине и форматирование кода не подходит ¯_ (ツ) _ / ¯

Идет работа над тем, чтобы расширения операторов стали реальностью: Проблема , 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
0 голосов
/ 06 января 2019

Если вы хотите использовать другого оператора, например (+.), вы можете сделать это:

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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...