在C#中定义F#'**'运算符

时间:2013-09-17 04:33:28

标签: c# f# operator-keyword exponent

我看到F#使用**运算符作为幂,因此2 ** 5 = 32。这与C#不同,您可以选择在自定义类型中使用“^”运算符,但由于某些原因,内置数字类型不会使用它。

但是如何在C#中实现**运算符以用于F#项目?

如果我在C#中这样做:

public static Integer operator ^(Integer left, Integer right)
{
    if (Integer.IsNaN(left) || Integer.IsNaN(right)) return NaN;
    return left.RaiseToPower(right);
}

它编译得很好,我可以像'+'运算符一样使用它,但这些都不适用于F#:

let intgr3 = intgr1 ** intgr2

let intgr3 = intgr1 ^ intgr2

在C#中,这不起作用:

public static Integer operator **(Integer left, Integer right)
{
    if (Integer.IsNaN(left) || Integer.IsNaN(right)) return NaN;
    return left.RaiseToPower(right);
}

那么如何在C#中定义**运算符的F#等价物呢? 感谢。

2 个答案:

答案 0 :(得分:7)

正如我在评论中所说,C#不允许您定义新的运算符,**不是C#中的运算符。 ^是一个运算符,但它是逻辑XOR运算符,而不是指数运算符。这给了我一个提示,即F#可能会将您的C#运算符转换为原生F#(^^^进行逻辑异或)。

所以,我创建了几个测试项目并使用了^的定义,这是我在F#中找到的:

open CSLib // CSLib is the C# library

let ( ** ) (x : Integer) (y : Integer) = x.RaiseToPower y

let x = new Integer()
let y = new Integer()

let a = x ^ y // error
let b = x ^^^ y // compiles, but looks like XOR
let c = x ** y // compiles

您可以在F#中定义新的全局运算符,但是如果您希望这是一个可能不可接受的通用库。

您可以通过在C#库中的Pow类型中定义公共静态方法Integer来定义在F#中使用的Exponentiation运算符:

public static Integer Pow(Integer left, Integer right)
{
    if (Integer.IsNaN(left) || Integer.IsNaN(right)) return NaN;
        return left.RaiseToPower(right);
}

然后,您可以直接在F#中使用它**。我会注意到C#中的重载运算符不是惯用的,所以对于C#用户来说,使用Pow方法看起来很自然。

答案 1 :(得分:2)

我相信你不能为你的对象定义一个**运算符的原因是这不是该语言支持的运算符之一。它不是一个公认的运营商.. 为什么不使用数学库 http://msdn.microsoft.com/en-us/library/system.math.pow.aspx