class pingouin = object
  method crie = Printf.printf "Iki.\n"
end

class super_pingouin = object
  inherit pingouin
  method vole = Printf.printf "Wheeeee!\n"
end


class type ['a] getter = object
  method get : 'a
end

class type ['a] setter = object
  method set : 'a -> unit
end

class type ['a] cell = object
  inherit ['a] getter
  inherit ['a] setter
end


class ['a] mycell init : ['a] cell = object
  val mutable content = init
  method get = content (* Notez la paresse! *)
  method set x = content <- x
end


(* Lesquels de ces types sont (proprement) habités? *)

let f : pingouin getter -> pingouin =
  assert false

let f : pingouin getter -> super_pingouin =
  assert false

let f : super_pingouin getter -> pingouin =
  assert false

let f : pingouin setter -> super_pingouin -> unit =
  assert false

let f : super_pingouin getter -> pingouin getter =
  assert false

let f : super_pingouin setter -> pingouin setter =
  assert false

let f : super_pingouin cell -> pingouin getter =
  assert false