Since c is defined as c : float -> float -> float, and you're writing f c, it must mean that f : (float -> float -> float) -> 'x (for some 'x that we don't know yet).
Since you also write f a, and we already know that f's argument is float -> float -> float, it means that a : float -> float -> float.
And this, in turn means that you can't subtract anything from a. It's a function, not a number. This is what the compiler is telling you.
Usually, when you get yourself in a situation where you don't understand what your type are doing, go ahead and add some type annotations. They will provide anchors for the compiler, sort of walls that the type inference cannot cross, and thus will contain the type inconsistencies.
For example, if you specify the type of f:
let dichotomy (f : float -> float) a b =
...
this immediately reveals an error at f c, stating that c was expected to be a float, but actually is a function.
If I understand correctly, what you meant to do is to apply f to (c a b), not to c itself. And then, correspondingly, return that same value in the tuples (a, c) and (c, b):
out (mywhile (fun (a, b) -> a - b < eps)
(fun (a, b) ->
let d = c a b
if f d * f a < 0. then (a, d) else (d, b)
)
(a, b))
(also, your zero was an int; I made it into a float by adding a dot after it)
aandbare inferred as'a -> 'b -> float, which is in fact a function type and does not support the-operator. When you change the first lambda passed tomywhileto(fun (a: float, b: float) -> a - b < eps), more errors show in the next line showing that the types ofa,bandcare incompatible, suggesting thatfmight not be inferred as the type you expect it to be, and you might want to fix its type with an annotation. - TeaDrivenDev