Given the following function types:

1
2
type T1 = A1 => B1
type T2 = A2 => B2

And the following function subtyping:

1
2
T1 <: T2
A1 => B1 <: A2 => B2

Implies:

1
2
A1 <: A2 # Contravariant
B1 :> B2 # Covariant

Supposed there is a function ‘f()’ which originally takes a function type ‘T2’ as an argument:

What are the conditions that would allow ‘T1’ be passed instead?

As far as ‘f()’ is aware, it calls the function passed as an argument with an input of type ‘A2’ and stores its return value in a variable of type ‘B2’.

‘f()’ can only call ‘T1’ with an argument ‘A2’ if ‘A1’ is a super-type of ‘A2’

1
A1 :> A2

Therefore contra-variant in ‘A1’ (‘A1’ is a subtype of ‘A2’ when ‘T1’ is a subtype of ‘T2’).

‘f()’ can only store a return value ‘A1’ in a variable of type ‘B2’ if ‘B2’ is a super-type of ‘B1’

1
B1 <: B2

Therefore covariant in ‘B1’ (‘B1’ is a subtype of ‘B2’ when ‘T1’ is a subtype of ‘T2’).