Liskov

object Liskov extends LiskovInstances
Companion
class
class Object
trait Matchable
class Any

Type members

Types

type <~<[-A, +B] = Liskov[A, B]

A convenient type alias for Liskov

A convenient type alias for Liskov

type >~>[+B, -A] = Liskov[A, B]

A flipped alias, for those used to their arrows running left to right

A flipped alias, for those used to their arrows running left to right

Value members

Concrete methods

def co[T[_], A, A2](a: Liskov[A, A2]): Liskov[T[A], T[A2]]

We can lift subtyping into any covariant type constructor

We can lift subtyping into any covariant type constructor

def co2[T[_, _], Z, A, B](a: Liskov[A, Z]): Liskov[T[A, B], T[Z, B]]
def co2_2[T[_, _], Z, A, B](a: Liskov[B, Z]): Liskov[T[A, B], T[A, Z]]
def co3[T[_, _, _], Z, A, B, C](a: Liskov[A, Z]): Liskov[T[A, B, C], T[Z, B, C]]
def co4[T[_, _, _, _], Z, A, B, C, D](a: Liskov[A, Z]): Liskov[T[A, B, C, D], T[Z, B, C, D]]
def contra[T[_], A, A2](a: Liskov[A, A2]): Liskov[T[A2], T[A]]

We can lift subtyping into any contravariant type constructor

We can lift subtyping into any contravariant type constructor

def contra1_2[T[_, _], Z, A, B](a: Liskov[A, Z]): Liskov[T[Z, B], T[A, B]]
def contra1_3[T[_, _, _], Z, A, B, C](a: Liskov[A, Z]): Liskov[T[Z, B, C], T[A, B, C]]
def contra1_4[T[_, _, _, _], Z, A, B, C, D](a: Liskov[A, Z]): Liskov[T[Z, B, C, D], T[A, B, C, D]]
def contra2_2[T[_, _], Z, A, B](a: Liskov[B, Z]): Liskov[T[A, Z], T[A, B]]
def contra2_3[T[_, _, _], Z, A, B, C](a: Liskov[B, Z]): Liskov[T[A, Z, C], T[A, B, C]]
def contra2_4[T[_, _, _, _], Z, A, B, C, D](a: Liskov[B, Z]): Liskov[T[A, Z, C, D], T[A, B, C, D]]
def contra3_3[T[_, _, _], Z, A, B, C](a: Liskov[C, Z]): Liskov[T[A, B, Z], T[A, B, C]]
def contra3_4[T[_, _, _, _], Z, A, B, C, D](a: Liskov[C, Z]): Liskov[T[A, B, Z, D], T[A, B, C, D]]
def contra4_4[T[_, _, _, _], Z, A, B, C, D](a: Liskov[D, Z]): Liskov[T[A, B, C, Z], T[A, B, C, D]]
def force[A, B]: Liskov[A, B]

Unsafely force a claim that A is a subtype of B.

Unsafely force a claim that A is a subtype of B.

def lift2[T[_, _], A, A2, B, B2](a: Liskov[A, A2], b: Liskov[B, B2]): Liskov[T[A, B], T[A2, B2]]

lift2(a,b) = co1_2(a) compose co2_2(b)

lift2(a,b) = co1_2(a) compose co2_2(b)

def lift3[T[_, _, _], A, A2, B, B2, C, C2](a: Liskov[A, A2], b: Liskov[B, B2], c: Liskov[C, C2]): Liskov[T[A, B, C], T[A2, B2, C2]]

lift3(a,b,c) = co1_3(a) compose co2_3(b) compose co3_3(c)

lift3(a,b,c) = co1_3(a) compose co2_3(b) compose co3_3(c)

def lift4[T[_, _, _, _], A, A2, B, B2, C, C2, D, D2](a: Liskov[A, A2], b: Liskov[B, B2], c: Liskov[C, C2], d: Liskov[D, D2]): Liskov[T[A, B, C, D], T[A2, B2, C2, D2]]

lift4(a,b,c,d) = co1_3(a) compose co2_3(b) compose co3_3(c) compose co4_4(d)

lift4(a,b,c,d) = co1_3(a) compose co2_3(b) compose co3_3(c) compose co4_4(d)

def liftF1[F[_, _], A, A2, R, R2](a: Liskov[A, A2], r: Liskov[R, R2]): Liskov[F[A2, R], F[A, R2]]

Lift subtyping into a unary function-like type

Lift subtyping into a unary function-like type

    liftF1(a,r) = contra1_2(a) compose co2_2(b)
def liftF2[F[_, _, _], A, A2, B, B2, R, R2](a: Liskov[A, A2], b: Liskov[B, B2], r: Liskov[R, R2]): Liskov[F[A2, B2, R], F[A, B, R2]]

Lift subtyping into a binary function-like type

Lift subtyping into a binary function-like type

    liftF2(a,b,r) = contra1_3(a) compose contra2_3(b) compose co3_3(c)
def liftF3[F[_, _, _, _], A, A2, B, B2, C, C2, R, R2](a: Liskov[A, A2], b: Liskov[B, B2], c: Liskov[C, C2], r: Liskov[R, R2]): Liskov[F[A2, B2, C2, R], F[A, B, C, R2]]

Lift subtyping into a ternary function-like type

Lift subtyping into a ternary function-like type

    liftF3(a,b,c,r) = contra1_4(a) compose contra2_4(b) compose contra3_4(c) compose co3_4(d)
def liftF4[F[_, _, _, _, _], A, A2, B, B2, C, C2, D, D2, R, R2](a: Liskov[A, A2], b: Liskov[B, B2], c: Liskov[C, C2], d: Liskov[D, D2], r: Liskov[R, R2]): Liskov[F[A2, B2, C2, D2, R], F[A, B, C, D, R2]]

Lift subtyping into a 4-ary function-like type

Lift subtyping into a 4-ary function-like type

def trans[A, B, C](f: Liskov[B, C], g: Liskov[A, B]): Liskov[A, C]

Subtyping is transitive

Subtyping is transitive

def unco[F[_] : Injective, Z, A](a: Liskov[F[A], F[Z]]): Liskov[A, Z]
def unco2_1[F[_, _] : Injective2, Z, A, B](a: Liskov[F[A, B], F[Z, B]]): Liskov[A, Z]
def unco2_2[F[_, _] : Injective2, Z, A, B](a: Liskov[F[A, B], F[A, Z]]): Liskov[B, Z]
def uncontra[F[_] : Injective, Z, A](a: Liskov[F[A], F[Z]]): Liskov[Z, A]
def uncontra2_1[F[_, _] : Injective2, Z, A, B](a: Liskov[F[A, B], F[Z, B]]): Liskov[Z, A]
def uncontra2_2[F[_, _] : Injective2, Z, A, B](a: Liskov[F[A, B], F[A, Z]]): Liskov[Z, B]

Implicits

Implicits

implicit
def refl[A]: Liskov[A, A]

Subtyping is reflexive

Subtyping is reflexive

implicit
def witness[A, B](lt: Liskov[A, B]): A => B

We can witness equality by using it to convert between types

We can witness equality by using it to convert between types

Inherited implicits

implicit
def isa[A, B >: A]: Liskov[A, B]

Lift Scala's subtyping relationship

Lift Scala's subtyping relationship

Inherited from
LiskovInstances
implicit

Subtyping forms a category

Subtyping forms a category

Inherited from
LiskovInstances