-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unchained to
on Measurement[SomeUnit] returns unchanged value and accepts unit of any quantity
#18
Comments
is it sufficient to wrap the unchained call? from std/sugar import dump
import unchained
import measuremancer
defUnit(Yard•Minute⁻¹)
defUnit(parsec•lbs)
proc to[T: SomeUnit](x: Measurement[T], U: typedesc[SomeUnit]): Measurement[U] =
x.value.to(U) ± x.error.to(U)
proc main() =
let x = 1.m
let y = 2.s
let xy = x / y
let mx = x ± 0.1.m
let my = y ± 0.1.s
let mxy = mx / my
dump x
dump y
dump xy
dump x.to(yd)
dump y.to(Minute)
dump xy.to(Yard•Minute⁻¹)
dump mx
dump my
dump mxy
dump mx.to(yd)
dump my.to(Minute)
dump mxy.to(Yard•Minute⁻¹)
doAssert not compiles(mxy.to(Liter))
doAssert not compiles(mxy.to(slug))
doAssert not compiles(mxy.to(parsec•lbs))
when isMainModule:
main() EDIT: I think I've found where the PR should end :P Measuremancer/measuremancer.nim Line 295 in 9e85f0b
|
with minimal edits to (currently private) import std/[importutils, tables, typetraits]
import unchained
import measuremancer {.all.}
privateAccess(Measurement)
proc changeType[T; U](tab: Derivatives[T], dtype: typedesc[U]): Derivatives[U] =
result = initDerivatives[U]()
for key, val in pairs(tab):
let nkey = (val: key.val.to(U), uncer: key.uncer.to(U), tag: key.tag)
result[nkey] = val.to(U)
proc to*[T: FloatLike, U](m: Measurement[T], dtype: typedesc[U]): Measurement[U] =
when T is U:
result = m
else:
result =
initMeasurement[U](m.val.to(U), m.uncer.to(U), m.der.changeType(dtype), m.id)
# ---------------------
type
MLength = Length | Measurement[Length]
MTime = Time | Measurement[Time]
Foo[TLength: MLength, TTime: MTime] = object
x: TLength
y: TTime
func init[TLength: MLength, TTime: MTime](T: typedesc[Foo], x: TLength, y: TTime): T =
T[TLength, TTime](x: x, y: y)
proc convertUnitsPairs*[T1](x: T1, T2: typedesc): T2 {.inline.} =
for xname, xf in fieldPairs(x):
for rname, rf in fieldPairs(result):
when xname == rname:
when xf is Measurement:
rf = xf.to(genericParams(rf.type).get(0))
else:
rf = xf.to(type(rf))
# ---------------------
from std/sugar import dump
defUnit(Yard•Minute⁻¹)
defUnit(parsec•lbs)
proc testSimple() =
let x = 1.m
let y = 2.s
let xy = x / y
let mx = x ± 0.1.m
let my = y ± 0.1.s
let mxy = mx / my
dump x
dump y
dump xy
dump x.to(yd)
dump y.to(Minute)
dump xy.to(Yard•Minute⁻¹)
dump mx
dump my
dump mxy
dump mx.to(yd)
dump my.to(Minute)
dump mxy.to(Yard•Minute⁻¹)
doAssert not compiles(mxy.to(Liter))
doAssert not compiles(mxy.to(slug))
doAssert not compiles(mxy.to(parsec•lbs))
let o1 = Foo.init(1.m, 2.s)
let o2 = o1.convertUnitsPairs(Foo[Yard, Minute])
dump o1
dump o2
doAssert not compiles(o1.convertUnitsPairs(Foo[Liter, slug]))
let m1 = Foo.init(1.m ± 0.001.m, 2.s ± 0.001.s)
let m2 = m1.convertUnitsPairs(Foo[Measurement[Yard], Measurement[Minute]])
dump m1
dump m2
doAssert not compiles(m1.convertUnitsPairs(Foo[Liter, slug]))
when isMainModule:
testSimple()
|
Hey! Sorry, been away for a few days. The first issue is that But more importantly, the issue is that it gets tricky with the other operations. It may very well be possible to solve this neatly, but it's not super straight forward. Feel free to give it a try and open a PR, but you need to make sure all the math operations on I might take a closer look at it one of these days myself. |
The text was updated successfully, but these errors were encountered: