Как написать функцию инфикса

Есть ли способ написать функцию infix, не используя символы? Что-то вроде этого:

let mod x y = x % y
x mod y

Возможно, ключевое слово перед "mod" или что-то еще.

Ответ 1

Существующий ответ правильный - вы не можете определить функцию infix в F # (просто пользовательский оператор инфикса). Помимо трюков с операторами труб, вы также можете использовать расширения:

// Define an extension member 'modulo' that 
// can be called on any Int32 value
type System.Int32 with
  member x.modulo n = x % n

// To use it, you can write something like this:
10 .modulo 3

Обратите внимание, что пространство перед . необходимо, так как в противном случае компилятор пытается интерпретировать 10.m как числовой литерал (например, 10.0f).

Я нахожу это немного более элегантным, чем использование трюка конвейера, потому что F # поддерживает как функциональный стиль, так и объектно-ориентированный стиль и методы расширения - в некотором смысле - близкие к неявным операторам из функционального стиля. Трюк с конвейером выглядит как небольшое злоупотребление операторами (и с первого взгляда это может показаться запутанным - возможно, более запутанным, чем вызов метода).

Тем не менее, я видел людей, использующих другие операторы вместо конвейера - возможно, наиболее интересной версией является эта (которая также использует тот факт, что вы можете пропускать пробелы вокруг операторов):

// Define custom operators to make the syntax prettier
let (</) a b = a |> b
let (/>) a b = a <| b    
let modulo a b = a % b 

// Then you can turn any function into infix using:
10 </modulo/> 3

Но даже это не действительно установленная идиома в мире F #, поэтому я, вероятно, по-прежнему предпочитаю расширения.

Ответ 2

Не то, что я знаю, но вы можете использовать левый и правый оператор трубы. Например

let modulo x y = x % y

let FourMod3 =  4 |> modulo <| 3