我开始为笛卡尔积和矩阵乘法定义我自己的算子.
矩阵和向量别名为列表:
type Matrix = float list list
type Vector = float list
Run Code Online (Sandbox Code Playgroud)
我可以通过写作来编写自己的初始化代码(并将笛卡尔产品纳入讨价还价)
let inline (*) X Y =
    X |> List.collect (fun x -> Y |> List.map (fun y -> (x, y)))
let createVector size f = 
    [0..size - 1] |> List.map (fun i -> f i)
let createMatrix rows columns f =
    [0..rows - 1] * [0..columns - 1] |> List.map (fun i j -> f i j)
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.问题是我的定义*消除了正常的定义,即使我的版本仅为Lists定义,而Lists没有自己的乘法运算符.
文档http://msdn.microsoft.com/en-us/library/vstudio/dd233204.aspx声明"新定义的运算符优先于内置运算符".但是,我没想到所有的数字化身都被消灭了 - 当然静态打字会解决这个问题吗?
我知道可以定义一个尊重类型的全局运算符,因为MathNet Numerics *用于矩阵乘法.我还想沿着这条道路前进,这需要打字系统优先考虑矩阵乘法而不是Matrix类型的笛卡尔乘积(它们本身就是列表).
有谁知道如何在F#中做到这一点?
Gus*_*Gus 14
这是(非惯用)解决方案:
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
Run Code Online (Sandbox Code Playgroud)
        Tom*_*cek 11
惯用解决方案是定义Matrix为新类型并将运算符添加为静态成员:
type Matrix = 
  | MatrixData of float list list
  static member (*) (MatrixData m1, MatrixData m2) = (...)
Run Code Online (Sandbox Code Playgroud)
let当您知道定义与其他任何内容不冲突,或者您在小范围内(在函数内)本地定义运算符时,定义使用的运算符非常有用.
对于自定义类型,最好将运算符定义为静态成员.这种方法的另一个好处是您的类型可以从C#(包括运算符)中使用.
要在您的示例中执行此操作,我必须将类型定义从类型别名(不是独立类型,因此它不能拥有自己的静态成员)更改为单个案例区分联合,它可以包含成员 - 但是无论如何,这可能是一个好主意.
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           1287 次  |  
        
|   最近记录:  |