6

我看到 F# 使用**运算符来获取幂,所以2 ** 5 = 32. 这与 C# 不同,在 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# 等价物呢?
谢谢。

4

2 回答 2

7

正如我在评论中所说,C# 不允许您定义新**的运算符,也不是 C# 中的运算符。^是一个运算符,但它是逻辑 XOR 运算符,而不是求幂运算符。这给了我一个提示,即 F# 可能会将您的 C# 运算符转换为本机 F#(^^^用于逻辑 XOR)。

因此,我创建了几个测试项目并使用您的定义^,这是我在 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中的类型中定义公共静态方法来定义在 F# 中使用的 Exponentiation 运算符:Integer

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

然后,您可以直接在 F# 中将其用作**. 我会注意到 C# 中的重载运算符不是惯用的,因此拥有一个Pow方法对于 C# 用户来说似乎很自然。

于 2013-09-17T05:17:55.710 回答
2

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

于 2013-09-17T04:37:41.987 回答