Skip to content

Instantly share code, notes, and snippets.

@japgolly
Created September 24, 2013 01:14
Show Gist options
  • Save japgolly/6679154 to your computer and use it in GitHub Desktop.
Save japgolly/6679154 to your computer and use it in GitHub Desktop.
Recursive types experimentation
object `^_^` {
trait Token
trait Value extends Token
trait P[A <: Token, B <: Value] extends Token
trait I[T <: Token]
// Conversions
implicit def AB_A[A <: Value, B <: Value](i: I[P[A, B]]): I[A] = i.asInstanceOf[I[A]]
implicit def AB_B[A <: Token, B <: Value](i: I[P[A, B]]): I[B] = i.asInstanceOf[I[B]]
implicit def PP_P[A <: Token, B <: Value, C <: Value](i: I[P[P[A,B],C]]): I[P[A,B]] = i.asInstanceOf[I[P[A,B]]]
// implicit def PP_Pv[A <: Token, B <: Value, C <: Value, IABC <% I[P[P[A,B],C]]](i: IABC): I[P[A,B]] = i.asInstanceOf[I[P[A,B]]]
// ***************************************************************
// Notice these conversions just manually compose existing ones.
// This is what I'm trying to work around.
// ***************************************************************
implicit def manual_ABC_A[A <: Value, B <: Value, C <: Value](i: I[P[P[A,B],C]]): I[A] = AB_A(PP_P(i))
implicit def manual_ABC_B[A <: Token, B <: Value, C <: Value](i: I[P[P[A,B],C]]): I[B] = AB_B(PP_P(i))
implicit def manual_ABCD_A[A <: Value, B <: Value, C <: Value, D <: Value](i: I[P[P[P[A,B],C],D]]): I[A] = AB_A(PP_P(PP_P(i)))
implicit def manual_ABCD_B[A <: Token, B <: Value, C <: Value, D <: Value](i: I[P[P[P[A,B],C],D]]): I[B] = AB_B(PP_P(PP_P(i)))
// Example data
trait A extends Value
trait B extends Value
trait C extends Value
trait D extends Value
type AB = P[A, B]
type ABC = P[AB, C]
type ABCD = P[ABC, D]
def testA(i: I[A]) = "A OK"
testA(new I[A]{})
testA(new I[AB]{})
testA(new I[ABC]{})
testA(new I[ABCD]{})
def testB(i: I[B]) = "b OK"
testB(new I[B]{})
testB(new I[AB]{})
testB(new I[ABC]{})
testB(new I[ABCD]{})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment