typescompiler-errorsreasontype-signature

Why is ReasonML throwing this type error?


I'm trying to create an iterative function that takes in an 'a => 'a function, and a natural number which indicates how many times to iterate this function. It will output another 'a => 'a function. Example input:

let func: int => int = num => x-2;

iterate(func, 3) would output func(func(func())) or x-6

However, I have this code

let rec iterate: ('a => 'a, int) => ('a => 'a) = (f, n) =>
switch(n){
    | 1 => f
    | x when x > 1 => f(iterate(f, n-1))
};

and it is giving me this error right under f(iterate(f, n-1))

This expression has type 'a => 'b but an expression was expected of type ('a => 'b, 'a) => 'b.

Edit: I believe it has something to do with the type signature in the first line being read by the compiler as ('a => 'a, int, 'a) => 'a for some reason and I have no clue why it would be reading it like that.


Solution

  • In the second branch you give f the result of calling iterate recursively, which according to your type annotation returns a function. Therefore 'a must be a function 'a => 'b. Also, if you return the result of calling f directly, that result must also be a function since that's what iterate should return.

    So you cannot return the result of applying f directly. You have to return a function that calls f with the value given to it, then passes its return value to the function returned from a recursive call to iterate (or the other way around), and then returns that value.