khebbie
khebbie

Reputation: 2503

Function returning function and not float in f#

Sorry for the really bad title, but I couldn't come up with a better one...

I am following Structure and interpretation of computer programs and am trying to do the example from section 1.1.7 about Netwon's method of seccessive approximation for finding square roots.

I try to implement it in F# and i believe I'm pretty close to getting there, but probably There is some kind of syntactic problem.

Here is my code (I used linqpad, hence the Dump()), below follows the question

let square a = a * a

let average a b = (a + b)/2.0

let a = average 2.0 1.0
a.Dump()

let improve guess x = average guess x

let i = improve 2.0 1.0
i.Dump()

let goodEnough guess x = abs (x - square(guess)) < 0.001

let g = goodEnough 3.0 4.0
g.Dump()

let g2 = goodEnough 2.0 4.0
g2.Dump()

let rec sqrtIterator guess x =
  if goodEnough guess x then guess
  else sqrtIterator(improve(guess x) x)

let sqrt x = sqrtIterator 1.0 x

I get an error on the recursive call to sqrtIterator saying: This expression was expected to have type float but here has type float -> float.

So it seems I am missing a parameter making it return a function taking one parameter, but I can not see whats wrong?

Upvotes: 2

Views: 166

Answers (3)

pad
pad

Reputation: 41290

Changing sqrtIterator(improve(guess x) x) to sqrtIterator (improve guess x) x would solve the problem.

From the first part of the expression in sqrtIterator:

if goodEnough guess x then guess

the type checker knows that guess is a float since goodEnough has already had type float -> float.

The else branch is expected to has type float as well. Consequently, sqrtIterator has type float -> float -> float.

However, you provided sqrtIterator(improve(guess x) x) in the else branch. The outermost parentheses indicate that improve(guess x) x is a single parameter which supposes to be a float.

Now sqrtIterator(improve(guess x) x) returns float -> float hence the above error message.

Upvotes: 5

John Palmer
John Palmer

Reputation: 25516

Your bracketing in sqrtIterator is slightly off - you need

  else sqrtIterator (improve guess x) x

Upvotes: 4

Stephen Swensen
Stephen Swensen

Reputation: 22297

Here is the problem fixed:

let rec sqrtIterator guess x =
  if goodEnough guess x then guess
  else sqrtIterator (improve guess x) x

Your parens were wrong.

Upvotes: 4

Related Questions