Global operator overloading in F#

Solution 1:

Here is the (non idiomatic) solution:

type Mult = Mult with
    static member inline ($) (Mult, v1: 'a list) = fun (v2: 'b list) -> 
        v1 |> List.collect (fun x -> v2 |> List.map (fun y -> (x, y))) : list<'a * 'b>
    static member inline ($) (Mult, v1:'a      ) = fun (v2:'a) -> v1 * v2 :'a

let inline (*) v1 v2 = (Mult $ v1) v2

Solution 2:

The idiomatic solution is to define Matrix as a new type and add operators as static members:

type Matrix = 
  | MatrixData of float list list
  static member (*) (MatrixData m1, MatrixData m2) = (...)

Operators defined using let are useful when you know that the definition does not conflict with anything else, or when you're defining the operator locally in a small scope (within a function).

For custom types, it is a good idea to define operators as static members. Another benefit of this approach is that your type will be usable from C# (including the operators).

To do this in your example, I had to change the type definition from type alias (which is not a stand-alone type and so it cannot have its own static members) to a single-case discriminated union, which can have members - but this is probably a good idea anyway.