2016-03-16 63 views
1

我想寫一個同質的元組類型,有點平行內置的元組類型在斯卡拉。斯卡拉高收斂類型的問題與新集合類

我有以下幾點:

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](這是合法的,正確的,但不太方便),但我可以不能讓它工作。

任何人有任何線索如何做到這一點?有沒有比我所做的更好的方式?

回答

2

我不得不四處移動的幾件事情,但是這似乎工作:

trait HomogeneousTupleFactory [H[_] <: HomogeneousTuple[_, H]] { 
    def makeHTuple[T] (values: Iterator[T]): H[T] 
} 

trait HomogeneousTuple [+T, H[_] <: HomogeneousTuple[_, H]] extends Product { 
    def getFactory: HomogeneousTupleFactory[H] 
    def map [U] (fcn: T => U): H[U] = { 
    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 
} 

基本上你需要HomogeneousTuple的H類參數去是一個高kinded類型,其餘的改動流出那個。

+0

作爲一個側面說明,你可能想從無形退房大中 - HTTPS:/ /github.com/milessabin/shapeless/blob/master/examples/src/main/scala/shapeless/examples/sized.scala –

+0

可能已經發誓我試過了,但我必須錯過或在某處添加了一個額外的[_]。非常感謝你。 –

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))