Reputation: 13985
Having a hierarchy
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
I would like to define global inline operator (+) (l:^v) (r:^v)
where ^v
would be required to inherit from Vector2D
, have some unit of measure float<'u>
and have constructor with two parameters of type float<'u>
.
Is it possible?
Upvotes: 2
Views: 1088
Reputation: 1302
You can try to do define the add function and then assign it to infix operator:
let add<[<Measure>]'u, 'v when 'v :> Vector2D<'u>> (l:^v) (r:^v) = l.Abs + r.Abs
let (+) left right = add left right
EDITED: This is how you can use it: IN this case left and right types has to match
let left = R2D(1.0<m>,1.0<m>)
let right = R2D(2.0<m>,2.0<m>)
let result = left + right
or you can try without matching types, still unit has to match
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
Upvotes: 4
Reputation: 817
You can define a separate +
for each subtype of Vector2D
like so:
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;}
You can inline
them if you want for performance as well, and can define other mathematical functions the same way if you don't want to deal with polymorphism and/or typechecking.
Upvotes: 2