Boolean'ın yanı sıra çeşitli sayısal türlerin değerlerini depolamak için C
sınıfını uygulamak istiyorum. Ayrıca, bu sınıfın örneklerinde, gerekirse, Int --> Double
ve Boolean -> Int
, yani Boolean + Boolean
, Int + Boolean
, Boolean + Int
, Int + Double
, Double + Double
vb. Mümkün olduğunda (Int
veya Double
) yazın.Sayısal türler arasında aritmetik sağlamak için örtülü dönüştürme nasıl ayarlanır?
Şimdiye kadar bu geldi:
Bu, bazı durumlarda çalışırabstract class SemiGroup[A] { def add(x:A, y:A):A }
class C[A] (val n:A) (implicit val s:SemiGroup[A]) {
def +[T <% A](that:C[T]) = s.add(this.n, that.n)
}
object Test extends Application {
implicit object IntSemiGroup extends SemiGroup[Int] {
def add(x: Int, y: Int):Int = x + y
}
implicit object DoubleSemiGroup extends SemiGroup[Double] {
def add(x: Double, y: Double):Double = x + y
}
implicit object BooleanSemiGroup extends SemiGroup[Boolean] {
def add(x: Boolean, y: Boolean):Boolean = true;
}
implicit def bool2int(b:Boolean):Int = if(b) 1 else 0
val n = new C[Int](10)
val d = new C[Double](10.5)
val b = new C[Boolean](true)
println(d + n) // [1]
println(n + n) // [2]
println(n + b) // [3]
// println(n + d) [4] XXX - no implicit conversion of Double to Int exists
// println(b + n) [5] XXX - no implicit conversion of Int to Boolean exists
}
(1, 2, 3) but does not için (4, 5). Bunun nedeni, tipin aşağıdan yukarıya doğru, ancak başka şekilde örtük olarak genişletilmemesidir.
def +[T, A <% T](that:C[T]):T = that.s.add(this.n, that.n)
ama bu derleyici için this.n
dönüştüremiyor öncelikle bu iki nedenden dolayı derleme değil: Bir bakıma,
def +[T <% A](that:C[T]) = s.add(this.n, that.n)
nasılsa benzer görünümde olacaktır ortağı yöntemi olması gerekir yöntemde T
yazın (A <% T
numaralı bağı belirtmemize rağmen) ve ikinci olarak, this.n
'u dönüştürdüyse bile, tür silme işleminden sonra iki +
yöntemi belirsiz olur.
Üzgünüz, bu çok uzun. Herhangi bir yardım çok takdir edilecektir! Aksi halde, tüm operasyonlar arasındaki tüm işlemleri açık bir şekilde yazmam gerekiyor. Ekstra tipler eklemek zorunda olsaydım tüylü olurdum (Complex
menüde ...).
Belki de tüm bunları bir arada gerçekleştirmek için başka bir yolu var mı? Bakıyorum basit bir şey varmış gibi hissediyorum.
Şimdiden teşekkürler!
Ahha! Bunun nasıl çalıştığını görüyorum - teşekkürler! 'Boolean' eklenmesi kolay oldu, ve 'Sayısal' LUB 'Karmaşık' için değiştirmek için çok zor olmayacak. Merak ediyorum - bu çözümü elinize geçirmiş görünüyorsunuz, bu bağlamda hangi bağlamda karşılaştınız? Ayrıca, bu çözümün performansını test etmeye çalıştım ve milyonlarca C'yi toplamaya çalıştım. [Int] 'ler, milyonlarca Int'ten daha beş kat daha yavaş görünüyor ... Başlamak için nasıl bir düşünce var? Bunu optimize et? – ostolop
Bunu IRC'de @extempore ile yapılan bir tartışma sırasında oynadım, bu benim için belirli bir problemi çözmüyordu. Dolaylı olarak 5x overhead çok kötü gelmiyor. 'Unify' yöntemini kullanmak yerine doğrudan' wc.a2b' ve 'wc.a2c' diyebilirsiniz. Şu anda 'NumeriC# plus' girişleri ve çıktıları kutlanıyor, umarım Scala'nın gelecekteki bir sürümü de bu problemi çözmek için bir yol bulacaktır. – retronym
@retronym Aslında ... Bu tartışmayı başlattım. :-) –