我正在尝试编写一个同质的元组类型,与scala中的内置元组类型有些相似。
我有以下内容:
trait HomogeneousTupleFactory [H <: HomogeneousTuple[_, H]] {
def makeHTuple[T] (values: Iterator[T]): HomogeneousTuple[T, H]
}
trait HomogeneousTuple [+T, H <: HomogeneousTuple[_, H]] extends Product {
def getFactory: HomogeneousTupleFactory[H]
def map [U] (fcn: T => U): HomogeneousTuple[U, H] = {
getFactory.makeHTuple(
this.productIterator.map(t => fcn(t.asInstanceOf[T]))
)
}
}
object HTuple2Factory extends HomogeneousTupleFactory[HTuple2[_]] {
def makeHTuple[T] (values: Iterator[T]): HTuple2[T] = {
new HTuple2(values.next, values.next)
}
}
class HTuple2[+T] (t1: T, t2: T) extends Tuple2(t1, t2)
with HomogeneousTuple[T, HTuple2[_]] {
def getFactory = HTuple2Factory
}
我正在努力让HTuple2.map[U]
返回HTuple2[U]
而不是HomogeneousTuple[U, HTuple2]
(这是合法且正确的,但不太方便),但我无法得到它起作用。
任何人都有任何线索如何做到这一点?有没有比我正在做的更好的方式?
答案 0 :(得分:2)
我不得不移动一些东西,但这似乎有效:
def retrieve_data(self, variable):
start_date = datetime.date.today() - datetime.timedelta(int(self.kwargs['days']))
invoice_set = InvoiceRecord.objects.filter(sale_date__gte=start_date)
total = 0
for invoice in invoice_set:
for sale in invoice.salesrecord_set.all():
total += getattr(self, variable)
return round(total)
基本上你需要HomogeneousTuple中的H类型param是一个更高级的类型,其余的更改都会从中流出。
答案 1 :(得分:0)
我没有足够的时间去发展,但似乎你正在寻找的是
sealed abstract class Nat
final abstract class Z extends Nat
final abstract class S[n <: Nat] extends Nat
trait Vect[n <: Nat, +A] {
def map[B](f : A => B) : Vect[n , B]
}
final case object VNil extends Vect[Z, Nothing] {
def map[B](f : Nothing => B) : Vect[Z, B] = this
}
final case class VCons[n <: Nat, A](head : A, tl : Vect[n, A]) extends Vect[S[n], A] {
def map[B](f : A => B) : Vect[S[n], B] = VCons[n, B](f(head), tl.map(f))
}
implicit final class ConsOps[A](val self : A) extends AnyVal {
def +++[n <: Nat](l : Vect[n, A]) : Vect[S[n], A] = VCons(self, l)
}
type _0 = Z
type _1 = S[_0]
type _2 = S[_1]
type Tuple0[A] = Vect[_0, A]
type Tuple1[A] = Vect[_1, A]
type Tuple2[A] = Vect[_2, A]
def inc[n <: Nat](v : Vect[n , Int]) : Vect[n , Int] = v.map((i : Int) => i + 1)
inc(2 +++ (3 +++ VNil))