;; The widening between the two function types is a value the caller builds — ;; a thunk, minted at the call — so there is exactly one place to build it: ;; around the whole argument. Nested inside one, there is no caller standing ;; where the thunk would have to go. ;; ;; The parameter here is (Fn [(Fn [$t] $t)] i32) and taker's address carries ;; (CFn [(CFn [i32] i32)] i32). Admitting that structurally binds $t and then ;; hands one word where the instance declares two, in a position no later pass ;; can widen: the catch-up that builds the outer thunk compares the whole ;; substituted parameter list and this mismatch is inside it. A call with no ;; type variables in it is refused, so this one is too. (defn taker [h (CFn [i32] i32)] i32 (h 1)) (defn hof [g (Fn [(Fn [$t] $t)] i32) k $t] i32 (g (fn [x] x))) (defn main [] i32 (println (hof taker 0)) 0)