2016-04-06 8 views
2

Bir türü scala'da bir değerle parametrelendirmek için var mı? o boyutu öylesine bir şey gibi olan Örneğin, bir [5,1] tarafından [2,3] matris çarpma olamaz çünkü Scala'da Boyut Parametrelendirme

val m1 = new Matrix[2,3]() 
val m2 = new Matrix[5,1]() 

val m3 = m1 multiply m2 

bir istisna olur ... bir matris parametrize? Bu, aynı zamanda Tuples veya Vektörler gibi diğer tiplerin uygulanmasında da yararlı olacaktır. Bunu başarmanın bir yolu bilen var mı? Hepimizin İşte 0'dan başlayarak doğal sayılardır türlerini tanımlayabilir Peano numaralarını kullanma

+1

Buna bağımlı yazım denir ve Scala sahip değildir. [Shapeless] (https://stackoverflow.com/questions/28287612/how-to-require-typesafe-constant-size-array-in-scala) sizi oraya götürür. –

+0

Bu durumda bağımlı (yazarak) olması gerekmez. Peano numaralarını kullanarak bir tür hiyerarşisi tanımlayabilirsiniz ve kodunuzu eşleştirdikleri sürece derler, aksi takdirde olmaz. –

cevap

4

onlar Nat ama _1 ve _2 her alt tipleri farklı türleri, bu nedenle varyans olmadan birbirinin yerine kullanılamaz vardır.

tanımlayın doğal sayılar:

scala> sealed trait Nat 
defined trait Nat 

scala> sealed trait _0 extends Nat 
defined trait _0 

scala> sealed trait Succ[N <: Nat] extends Nat 
defined trait Succ 

scala> type _1 = Succ[_0] 
defined type alias _1 

scala> type _2 = Succ[_1] 
defined type alias _2 
kendi parametre türlerinde Matrix değişmez olduğu

:

scala> case class Matrix[A <: Nat, B <: Nat](ignoreThis: String) 
defined class Matrix 

çarpma işlevi de değişmez olduğu:

scala> def multiply[R1 <: Nat, C1 <: Nat, C2 <: Nat](m1: Matrix[R1, C1], m2: Matrix[C1, C2]) = Matrix[R1, C2](m1.ignoreThis + m2.ignoreThis) 
multiply: [R1 <: Nat, C1 <: Nat, C2 <: Nat](m1: Matrix[R1,C1], m2: Matrix[C1,C2])Matrix[R1,C2] 

Derleyici yapacak çekler sizin için, boyut eşleşmesi:

01 Maç derleme zamanı hatası yok
scala> multiply(Matrix[_1, _2]("one"), Matrix[_2, _1]("two")) 
res0: Matrix[_1,_1] = Matrix(onetwo) 

boyutlar çalışma zamanı daha iyidir:

scala> multiply(Matrix[_1, _2]("one"), Matrix[_1, _1]("two")) 
<console>:19: error: type mismatch; 
found : Matrix[_1(in object $iw),_2] 
    (which expands to) Matrix[Succ[_0],Succ[Succ[_0]]] 
required: Matrix[_1(in object $iw),Succ[_ >: _0 with _1(in object $iw) <: Nat]] 
    (which expands to) Matrix[Succ[_0],Succ[_ >: _0 with Succ[_0] <: Nat]] 
Note: _2 <: Succ[_ >: _0 with _1 <: Nat], but class Matrix is invariant in type B. 
You may wish to define B as +B instead. (SLS 4.5) 
     multiply(Matrix[_1, _2]("one"), Matrix[_1, _1]("two")) 
          ^
<console>:19: error: type mismatch; 
found : Matrix[_1(in object $iw),_1(in object $iw)] 
    (which expands to) Matrix[Succ[_0],Succ[_0]] 
required: Matrix[Succ[_ >: _0 with _1(in object $iw) <: Nat],_1(in object $iw)] 
    (which expands to) Matrix[Succ[_ >: _0 with Succ[_0] <: Nat],Succ[_0]] 
Note: _1 <: Succ[_ >: _0 with _1 <: Nat], but class Matrix is invariant in type A. 
You may wish to define A as +A instead. (SLS 4.5) 
     multiply(Matrix[_1, _2]("one"), Matrix[_1, _1]("two")) 
                ^

Ben dolayısıyla ignoreThis yer tutucu fiili çarpma uygulama yazmak için tembel oldu.

+0

Ooh vay harika! Herhangi bir kütüphane kullanıyor musunuz? –

+0

Bu saf Scala, özel kütüphane yok. Eminim, tür güvenli matematik yapıları ve operasyonlarının daha doğru ve eksiksiz uygulamaları olmalı. –

+0

Scala'nın bunu yapmak için gereken çarpıklıkları nasıl desteklediğini göstermesi harika, ancak bu hata iletileri ... opak. Ve matkat Matrix [_100, _256] ya da bir şey yapmak için gerekli muazzam olurdu. –