1

Given:

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

Using the above hierarchy, how can I define a function that, at compile-time, has a List of type A that is either all K's or L's, i.e. the super-type must be either K or L, but not F?

Example:

f(List(K1, K1)) would compile since the list's super-type is K

but

f(List(K1, L1)) would not since the list's super-type is F

1
  • You could use Either, though I've never liked its syntax much Commented Sep 22, 2016 at 18:42

1 Answer 1

1

You can start with Miles Sabin's answer at Enforce type difference and adapt:

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]    ^
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.