2016-09-22 190 views
1

考虑:指定类型约束约束

sealed trait F 
sealed trait K extends F 
case object K1 extends K 
sealed trait L extends F 
case object L1 extends L 

使用上面的层次,我怎么可以定义一个函数,在编译时,有A类型要么是所有K的或L“的名单s,即超级类型必须是KL,但不是F

例子:

f(List(K1, K1))将编译由于该表的超类型是K

f(List(K1, L1))不会因为名单的超类型是F

+0

你可以使用'Either',尽管我从来不喜欢它的语法 – spiffman

回答

1

您可以用数开始Sabin的回答为Enforce type difference并修改为:

implicit def notSubtype[A, B]: >!>[A, B] = null 
implicit def ambig1[A, B >: A]: >!>[B, A] = null 
implicit def ambig2[A, B >: A]: >!>[B, A] = null 

def f[A >: K with L](xs: List[A])(implicit ev: A >!> F) = xs 


f(List(K1, K1)) // compiles 

f(List(K1, L1)) 
[error] /tmp/rendererB0Um6L4t45/src/main/scala/test.scala:23: ambiguous implicit values: 
[error] both method ambig1 in object Main of type [A, B >: A]=> >!>[B,A] 
[error] and method ambig2 in object Main of type [A, B >: A]=> >!>[B,A] 
[error] match expected type >!>[F,F] 
[error] f(List(K1, L1)) 
[error] ^