2015-01-18 4 views
2

다음 코드 고려해 Foo(s)Foo[Seq[T]] forSome {type T}을 입력 가지고 Bar(s)Bar[Seq[T]] forSome {type T}을 입력 있기 때문에,스칼라의 실존 형 수량 한정자의 범위를 확장하여 두 변수에 같은 유형이 있음을 유형 검사기에 알리는 방법이 있습니까?

case class Foo[A](a:A) 
case class Bar[A](a:A) 

def f[B](foo:Foo[Seq[B]], bar:Bar[Seq[B]]) = foo.a ++ bar.a 

val s : Seq[T] forSome {type T} = Seq(1, 2, 3) 

f(Foo(s), Bar(s)) 

마지막 줄에 체크를 입력 실패를, 즉 각각 자신의 존재 한정사가 있습니다.

이 문제가 발생합니까? 사실 내가 컴파일시에 s에 대해 알고있는 것은 그러한 실존 유형을 가지고 있다는 것입니다. Foo(s)Bar(s)을 실존 한정 기호의 범위에 포함 시키려면 어떻게해야합니까?

의미가 있습니까? 저는 스칼라와 멋진 유형에 대해 꽤 새로운 것입니다.

답변

1

나는 그것이 리팩토링의 작은 비트와 함께이 일을하는 것이 가능 실현 :

case class Foo[A](a:A) 
case class Bar[A](a:A) 

def f[B](foo:Foo[Seq[B]], bar:Bar[Seq[B]]) = foo.a ++ bar.a 
def g[B](s1:Seq[B], s2:Seq[B]) = f(Foo(s1), Bar(s2)) 

val s : Seq[T] forSome {type T} = Seq(1, 2, 3) 

g(s) 

하는 것은 기본적으로 내가 전화를 래핑이 작업을 수행 할 수 있습니다

한 가지 방법은 태그 유형입니다 두 개의 시퀀스가 ​​동일한 유형을 갖도록 보장하는 다른 함수 g에서 f으로 변경하십시오.

1

명확하게하기 위해,

val s : Seq[T] forSome {type T} = Seq(1, 2, 3) 

내가 대답은이 질문에 대해 더 생각하지

val s: Seq[_] = Seq(1, 2, 3) 

에 해당합니다. 범위 또는 구체적 유형에있는 유형 매개 변수/유형 멤버를 사용해야합니다. http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagged-types.html

type Tagged[U] = { type Tag = U } 
type @@[T, U] = T with Tagged[U] 
def tag[A, B](a: A): @@[A, B] = a.asInstanceOf[@@[A, B]] 
trait ThisExistsAtCompileTime 

case class Foo[A](a:A) 
case class Bar[A](a:A) 

def f[B](foo:Foo[Seq[B]], bar:Bar[Seq[B]]) = foo.a ++ bar.a 

val s : Seq[@@[T, ThisExistsAtCompileTime] forSome {type T}] = Seq(1, 2, 3) map { x => tag[Any, ThisExistsAtCompileTime](x) } 

f(Foo(s), Bar(s))