Sadece scala standart kitaplığını kullanmak isterseniz, Numeric[T]
'a bakın. Durumunuzda, tamsayı olmayan bir bölüm yapmak istediğinizden, Numeric
'un Fractional[T]
alt sınıfını kullanmanız gerekir.
Kod, scala standart kitaplık türlerini kullanarak nasıl görüneceğini gösterir. Fractional
'un Ordered
'dan çıktığını unutmayın. Bu, bu durumda uygundur, ancak matematiksel olarak da jenerik değildir. Örneğin. Sipariş edilmediğinden Complex
için Fractional[T]
tanımlayamazsınız.
def bucketiseScala[T: Fractional](buckets: Seq[T], candidate: T): T = {
// so we can use integral operators such as + and/
import Fractional.Implicits._
// so we can use ordering operators such as <. We do have a Ordering[T]
// typeclass instance because Fractional extends Ordered
import Ordering.Implicits._
// integral does not provide a simple way to create an integral from an
// integer, so this ugly hack
val two = (implicitly[Fractional[T]].one + implicitly[Fractional[T]].one)
buckets.foldLeft(buckets.head) { (x, y) =>
val midPoint = (x + y)/two
if (candidate < midPoint) x else y
}
}
Ancak ciddi jenerik sayısal hesaplamalar için ben
spire bir göz alarak öneririz. Sayısal tiplerin çok daha ayrıntılı bir hiyerarşisi sağlar. Spire Tipleri ayrıca uzmanlaşmıştır ve bu nedenle çoğu zaman doğrudan ilkellerle çalışmak kadar hızlıdır. İşte
sivri kullanarak olmazdı örnek kullanmak için yapılması gerekenler:
// imports all operator syntax as well as standard typeclass instances
import spire.implicits._
// we need to provide Order explicitly, since not all fields have an order.
// E.g. you can define a Field[Complex] even though complex numbers do not
// have an order.
def bucketiseSpire[T: Field: Order](buckets: Seq[T], candidate: T): T = {
// spire provides a way to get the typeclass instance using the type
// (standard practice in all libraries that use typeclasses extensively)
// the line below is equivalent to implicitly[Field[T]].fromInt(2)
// it also provides a simple way to convert from an integer
// operators are all enabled using the spire.implicits._ import
val two = Field[T].fromInt(2)
buckets.foldLeft(buckets.head) { (x, y) =>
val midPoint = (x + y)/two
if (candidate < midPoint) x else y
}
}
hatta neredeyse aynı böyle örnek (yazabilmesi için, bir Field[T]
mevcutsa Spire bile T
için tamsayılar otomatik dönüşüm sağlar jenerik olmayan versiyon). Ancak, yukarıdaki örneklerin anlaşılması daha kolay olduğunu düşünüyorum.
// this is how it would look when using all advanced features of spire
def bucketiseSpireShort[T: Field: Order](buckets: Seq[T], candidate: T): T = {
buckets.foldLeft(buckets.head) { (x, y) =>
val midPoint = (x + y)/2
if (candidate < midPoint) x else y
}
}
Güncelleme: kulesiyle çok güçlü ve jenerik değil, aynı zamanda bir acemi için biraz kafa karıştırıcı olabilir. Özellikle işler işe yaramadığında. İşte temel yaklaşımı ve bazı sorunları açıklayan bir excellent blog post.
Tamam, teşekkürler. Mesele şu ki, Int (http://www.scala-lang.org/api/current/index.html#scala.Int) için scala dokümanlar, uzandığı özellikleri listelemiyorlar. '. Int'nın hangi özelliklerini genişletebileceğimi nasıl öğrenebilirim ki, kendim için “Numeric [T]” yi bulabilirdim? – jbrown
@jbrown Sıralama bir [typeclass] 'dir (http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html). Tipler, devralma kullanılarak çalışmaz. –
Peki, Intel'in hangi tip belgelerin geçerli olduğu belgelerine bakarak nasıl bilebilirdik? – jbrown