Hello,

I’m fought for a while with a piece of code that would not typecheck, and I’m curious if there’s an obvious way to get it to typecheck.

Take this code:

```
type tree =
| Leaf of int
| Node of (int * tree * tree)
let rec f (g : int -> 'a) tree : 'a =
match tree with
| Leaf i -> g i
| Node (i, l, r) -> if i >= 0 then f g l else f g r
let x = f (fun i -> "s") (Leaf 0)
let y = f (fun i -> i) (Leaf 0)
```

Running this in the playground gives us, as expected,

```
type tree = Leaf of int | Node of (int * tree * tree)
val f : (int -> 'a) -> tree -> 'a = <fun>
val x : string = "s"
val y : int = 0
```

However, let’s say that I want `f`

to call itself with a different `g`

than the one passed as argument temporarily. For example:

```
type tree =
| Leaf of int
| Node of (int * tree * tree)
let rec f (g : int -> 'a) tree : 'a =
match tree with
| Leaf i -> g i
| Node (i, l, r) ->
if (i == 0) then
let g' i = Leaf i in
let ret = f g' (Node (12, Leaf(42), Leaf (24))) in
f g ret
else
if i >= 0 then f g l else f g r
let x = f (fun i -> "s") (Leaf 0)
let y = f (fun i -> i) (Leaf 0)
```

Suddenly, this does not type-check anymore, since it infers the following, which is quite inconvenient:

```
val f : (int -> tree) -> tree -> tree = <fun>
```

Suddenly, the `g`

argument must return a `tree`

. Is there a way to get this function to keep inferring that `g : int -> 'a`

?

In my current code (which is much more complex, but let’s simplify here), my `g`

function is of type

`int -> ('a, int)`

and I only need the int in my internal recursive call, so I create a function g that returns `((), the_thing_I_need)`

, and then discard the unit, and it fails to typecheck.

I did manage to get it to work by doing `let g i = (Obj.magic (), the_thing_I_need)`

but it’s not pretty and I’m not even 100% sure it’s safe.