2016-09-22 192 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] ^