F#中的全局运算符重载 [英] Global operator overloading in F#

查看:63
本文介绍了F#中的全局运算符重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为笛卡尔乘积和矩阵乘法定义自己的运算符.

I'm starting down the road of defining my own operators for Cartesian products and matrix multiplication.

以矩阵和向量作为列表的别名:

With matrices and vectors aliased as lists:

type Matrix = float list list
type Vector = float list

我可以通过编写自己的初始化代码(并使笛卡尔产品成为便宜货)

I can write my own initialisation code (and get a Cartesian product into the bargain) by writing

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)

到目前为止,一切都很好.问题是我的*定义抹去了常规定义,即使我的版本仅针对Lists定义,而Lists没有自己的乘法运算符.

So far so good. The problem is that my definition of * wipes out the normal definition, even though my version is only defined for Lists, which don't have their own multiplication operator.

文档 http://msdn.microsoft.com/en-us/library/vstudio /dd233204.aspx 指出新定义的运算符优先于内置运算符".但是,我不希望所有数字化身都被淘汰掉-肯定是静态类型会解决这个问题吗?

The documentation http://msdn.microsoft.com/en-us/library/vstudio/dd233204.aspx states that "newly defined operators take precedence over the built-in operators". However, I wasn't expecting all of the numerical incarnations to be wiped out -- surely static typing would take care of this?

我知道可以定义一个尊重类型的全局运算符,因为MathNet Numerics使用*进行矩阵乘法.我也想走这条路,这将要求打字系统将矩阵乘法的优先级高于Matrix类型(它们本身就是列表)的笛卡尔积.

I know it is possible to define a global operator that respects types, because MathNet Numerics uses * for matrix multiplication. I would also like to go down that road, which would require the typing system to prioritise matrix multiplication over the Cartesian product of Matrix types (which are themselves lists).

有人知道如何在F#中执行此操作吗?

Does anyone know how to do this in F#?

推荐答案

(非惯用的)解决方案是这里:

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

这篇关于F#中的全局运算符重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆