2011-10-21 13 views
6

Wystąpił problem podczas pracy z funkcją Jednostki miary w metascala, zdefiniowaną w pliku Units.scala.Błąd sprawdzania zależności/typu podczas korzystania z obliczeń na poziomie typu

W pozostałej części tego pytania będę używał schematu uproszczonego, z tylko jednym typem jednostki, długość.

Więc gdzie w rzeczywistości rodzajem wygląda

Quantity[_1, _0, _0, _0, _0, _0, _0] 
     ^^^^^^^
      | | | | | | | 
      | Mass | Crncy.| Mol | 
     Length Time Temp. Lum.Intensity 

to będzie wystarczające do wykazania problem:

Quantity[_1] 
     ^
      | 
     Length 

Jak tylko typ należy wywnioskować, problem zaczyna.

Rozważmy następujący przykład (także rzucić okiem na kod z UnitsTest.scala):

val length: Quantity[_1] = m(5) 
val area: Quantity[_2] = length * length // (1) Works 
val dist: Quantity[_1] = area/length // (2) Doesn't work! 

pojawia się błąd w ostatnim wierszu mówi:

type mismatch; 
    found : 
    scalax.units.Units.Quantity[ 
     scalax.units.Subtractables.-[ 
     scalax.units.Integers._2, 
     scalax.units.Integers._1 
     ] 
    ] 

    required: 
    scalax.units.Units.Quantity[ 
     scalax.units.Integers._1 
    ] 

Wygląda na to kompilator może” t wymyślić, że dany typ jest równy Quantity[_1], gdy "odejmowanie wymiaru", np. sol. przejście z obszaru dist jak w (1):

Quantity[_2 - _1] <<not equal to>> Quantity[_1] 

Mylące jest to, że to działa, gdy „dodanie wymiaru” e. sol. począwszy od długości do obszaru jak w (2).

Quantity[_1 + _1] <<equal to>> Quantity[_2] 

(Przepraszam za nie wklejanie cały kod tutaj, to jest po prostu zbyt dużo starałem się zminimalizować moim przykładem, ale nie udało mi Dlatego ja tylko łączenie. do tego.)

Odpowiedz

2

Typ Sub z Subtractable brakuje w funkcji MInt. Prostą definicją, która sprawi, że będzie działać, byłoby dodanie dodatniego wyniku ujemnego, gdy chcesz odjąć typ w MSucc i .

sealed trait MInt extends Visitable[IntVisitor] with Addable with Subtractable { 
    type AddType = MInt 
    type SubType = MInt 
    type Add[I <: MInt] <: MInt 
    type Sub[I <: MInt] <: MInt 
    type Neg <: MInt 
    type Succ <: MInt 
    type Pre <: MInt 
} 

final class _0 extends Nat { 
    type Add[I <: MInt] = I 
    type Sub[I <: MInt] = I#Neg 
    type AcceptNatVisitor[V <: NatVisitor] = V#Visit0 
    type Neg = _0 
    type Succ = MSucc[_0] 
    type Pre = Succ#Neg 
} 

final class MSucc[P <: Nat] extends Pos { 
    type This = MSucc[P] 
    type Add[N <: MInt] = P#Add[N]#Succ 
    type Sub[N <: MInt] = Add[N#Neg] 
    type AcceptNatVisitor[V <: NatVisitor] = V#VisitSucc[P] 
    type Neg = MNeg[This] 
    type Pre = P 
    type Succ = MSucc[This] 
} 

final class MNeg[P <: Pos] extends MInt { 
    type Add[N <: MInt] = P#Add[N#Neg]#Neg 
    type Sub[N <: MInt] = Add[N#Neg] 
    type Accept[V <: IntVisitor] = V#VisitNeg[P] 
    type Neg = P 
    type Succ = P#Pre#Neg 
    type Pre = P#Succ#Neg 
} 

Jeszcze jedno, sposób w Quantity/ należy podzielić jego parametry, a nie je mnożyć!

+0

Tak, to jest poprawka. Popełniłem dwie poprawki do repozytorium MetaScala. –

Powiązane problemy