Solution (source code)

= Solution

\b[`Fun[Base, Derived]` can safely supply a `Fun[Base, Base]` contract; `Fun[Base, Base]` cannot in general supply a `Fun[Base, Derived]` contract.] The input obligation is unchanged, while a derived result satisfies every base-result promise. This is the covariant output rule of <function> <subtyping>.

With the invariant printed <trait>, implement the safe view explicitly:

``
def widenResult(f: Fun[Base, Derived]): Fun[Base, Base] =
  new Fun[Base, Base] {
    def apply(x: Base): Base = f(x)
  }
``

Using the illustrative classes from part i, an unsafe substitution would let a client assume a derived-only operation on a result that is merely a base <software object>:

``
val broadResult = new Fun[Base, Base] {
  def apply(x: Base): Base = new Base
}
def derivedResultClient(f: Fun[Base, Derived]): Int =
  f(new Base).special()
// derivedResultClient(broadResult) must be rejected.
``

The direct, variance-aware <object interface> that would express both safe directions is `trait Fun[-S, +T] { def apply(x: S): T }`. Its <object method> consumes the contravariant parameter and produces the covariant parameter. This is an explicitly proposed variant of the printed invariant declaration, not an assumption that its annotations were already present.