2016-03-16 68 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))