我正在尝试编写一些可以使用标量或向量的数字代码(在本例中分别是来自 DiffSharp 的 D 和 DV 类型)。有时我希望能够使用其中任何一个,因此我为它们定义了一个可区分的联合:
type IBroadcastable =
| Scalar of D
| Vect of DV
对于这两种类型,许多运算符已经重载,因此要在IBroadcastable
我将这样的代码添加到联合中:
static member Exp x =
match x with
| Scalar x -> Scalar (exp x)
| Vect x -> Vect (exp x)
这看起来非常多余。有什么方法可以在联合上使用运算符而无需为其编写新的重载吗?或者我应该使用不同的模式(即不是受歧视的工会)?我想使用这种类型的一个例子:
let ll (y: IBroadcastable) (theta: IBroadcastable) = y*theta-(exp theta)
The *
and -
将会有更复杂的行为(数组广播),这是有必要描述我自己的,但是exp
运算符很简单,如上。这需要是一个函数,因为我希望能够部分应用 y 参数,使用 DiffSharp 获取梯度,并相对于 theta 参数最大化它。
从根本上讲,由于您正在定义一个抽象,因此您需要根据该抽象来定义您的操作。这是一项成本,必须通过它在代码中其他地方为您提供的便利来抵消。
您可能想知道 F# 是否允许您在特定情况下剪切样板。除了使用function
关键字,不是真的,因为两个分支实际上都在做不同的事情:绑定变量的类型x
是不同的,并且您将它们包装在不同的联合箱中。如果你确实在做同样的事情,你可以这样写,例如:
type DU =
| A of float * float
| B of float * string
with
static member Exp = function
| A (b, _)
| B (b, _) -> exp b // only write the logic once
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)