Re: help a newbie with Lazy
| Newsgroups | gmane.comp.lang.ocaml.beginners |
|---|---|
| Message-ID | <CAOOOohSwNnFcJ3TPG6tGHEXcCkrbA729y6G+zhvGYnb7oQJrsA@mail.gmail.com> |
Hi John,
Indeed OCaml is not lazy by default, and this is why you get an error.
Using an infinite data structure in this case does not make things very
clear IMO, compared to direct recursive calls. How about this:
let rec newton f n y =
if n = 0 then y
else
f (newton f (n - 1) y) y;;
let newton_sqrt = newton (fun x y -> 0.5 *. (x +. y /. x));;
The use of lazy values is much less frequent in OCaml than in Haskell, so
if you're learning the language I think you'd get a better impression by
looking at more idiomatic examples. There are a handful of very good
resources out there. Now to answer your initial question, this is how I'd
translate the algorithm in OCaml:
type 'a sequence = Cons of ('a * 'a sequence Lazy.t)
let rec repeat f x = Cons (x, (lazy (repeat f (f x))))
let rec within eps (Cons (a, lazy (Cons (b,rest)))) = if abs_float(a -.
b)<eps then b else within eps (Cons (b, rest))
let next y x = (x +. y /. x) /. 2.
let newton_sqrt x0 eps y = within eps (repeat (next y) x0)
Cheers,
Philippe.
2014-08-02 23:15 GMT+02:00 'John A. Dodson' [email protected]
[ocaml_beginners] <[email protected]>:
>
>
> Hi. I am trying to teach myself OCaml, so I was starting with the examples
> from John Hughes' paper on functional design. In particular I was trying to
> get his algorithm for square root to work -
>
> let next y x = (x +. y /. x) /. 2.;;
> let rec repeat f x = x::repeat f (f x);;
> let rec within eps (a::b::rest) = if abs_float(a -. b)<eps then b else
> within eps (b::rest);;
> let newton_sqrt x0 eps y = within eps (repeat (next y) x0);;
>
> newton_sqrt 4. 1e-5 17.;;
>
> This fails, because I guess OCaml is not lazy by default. I suppose I need
> to apply a 'lazy' and a 'Lazy.force' in here somewhere, but I'm not sure
> where. I made various attempts without success. Can anyone give me a hint?
>
> Regards,
> John
>
>
>
>