具有层次结构
open FSharp.Data.UnitSystems.SI.UnitSymbols
type Vector2D<[<Measure>] 'u>(x: float<'u>, y: float<'u>) =
member val Abs =
let squared = float (x*x+y*y)
LanguagePrimitives.FloatWithMeasure<'u> (Math.Sqrt squared)
type R2D =
inherit Vector2D<m>(x, y)
member val X = x
member val Y = y
type V2D(vx, vy) =
inherit Vector2D<m/s>(vx, vy)
member val Vx = vx
member val Vy = vy
type A2D(ax, ay) =
inherit Vector2D<m/s^2>(ax, ay)
member val Ax = ax
member val Ay = ay
我想定义全局内联运算符(+) (l:^v) (r:^v)
,其中需要^v
从Vector2D
继承,具有度量单位float<'u>
,并且具有构造函数带有两个float<'u>
类型的参数。
有可能吗?
答案 0 :(得分:4)
您可以尝试定义add函数,然后将其分配给infix运算符:
let add<[<Measure>]'u, 'v when 'v :> Vector2D<'u>> (l:^v) (r:^v) = l.Abs + r.Abs
let (+) left right = add left right
已编辑: 这是您可以使用的方式: 在这种情况下,左右类型必须匹配
let left = R2D(1.0<m>,1.0<m>)
let right = R2D(2.0<m>,2.0<m>)
let result = left + right
或者您可以尝试不使用匹配类型,但仍然必须匹配
let left:Vector2D<m> = R2D(1.0<m>,1.0<m>) :> Vector2D<m>
let right:Vector2D<m> = A2D2(2.0<m>,2.0<m>) :> Vector2D<m>
let result = left + right
答案 1 :(得分:2)
您可以为+
的每个子类型定义一个单独的Vector2D
,如下所示:
type V2D(vx, vy) =
inherit Vector2D<m/s>(vx, vy)
member val Vx = vx
member val Vy = vy
static member (+) (l:V2D, r:V2D) = V2D(l.Vx + r.Vx, l.Vy + r.Vy)
type A2D(ax, ay) =
inherit Vector2D<m/s^2>(ax, ay)
member val Ax = ax
member val Ay = ay
static member (+) (l:A2D, r:A2D) = A2D(l.Ax + r.Ax, l.Ay + r.Ay)
let v1 = V2D(2.0<m/s>, 3.0<m/s>)
let v2 = V2D(2.0<m/s>, 3.0<m/s>)
v1 + v2 //yields in FSI: val it : V2D = FSI_0002+V2D {Abs = 7.211102551; Vx = 4.0; Vy = 6.0;}
如果您还想提高性能,也可以inline
,如果不想处理多态和/或类型检查,可以用相同的方式定义其他数学函数。