A solution that works in this specific example and does not require to rewire the logic is
to return the printing function inside a record with the right universal quantification:

...
type debug = {fn: 'a. ('a, unit, string, unit) format4 -> 'a }[@@unboxed];;
let udebug = {fn=debug}
let give_fn () = Some udebug
...
  | Some {fn} ->
    fn "fn";
    fn "fn param: %s" param