Agafovna
Agafovna

Reputation: 11

F#. Expecting a type supporting the operator '-' but given a function type

I'm new to F# and have some compilation problems in this code fragment:

let rec mywhile p f s =
    if p s then s
    else
       let s1 = f s
       mywhile p f s1

let eps = 0.001

let dichotomy f a b = 
    let out (a, b) = a
    let c a b = (a + b) / 2.
    out (mywhile (fun (a, b) -> a - b < eps)
        (fun (a, b) -> if f c * f a < 0 then (a, c) else (c, b))
        (a, b))

In particular, here: a - b < eps, then (a, c)

Expecting a type supporting the operator '-' but given a function type. You may be missing an argument to a function.

Upvotes: 0

Views: 374

Answers (1)

Fyodor Soikin
Fyodor Soikin

Reputation: 80734

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)

Upvotes: 3

Related Questions