Version française
Home     About     Download     Resources     Contact us    
Browse thread
forbidden construct as right hand side of "let rec"
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Xavier Leroy <Xavier.Leroy@i...>
Subject: Re: [Caml-list] forbidden construct as right hand side of "let rec"
Mathias Kende wrote:

> I need to write something like this :
> 
> 	let f f i = if i = 0 then 1 else i * f (i - 1)
> 	let rec g = f g
> 
> Of course the compiler won't let me write it (even if the OCaml type
> system is happy):
> 	"This kind of expression is not allowed as right-hand side of `let rec'"
In general, the best thing to do in this case is to switch to lazy
evaluation:

# let f f i = if i = 0 then 1 else i * Lazy.force f (i-1);;
val f : (int -> int) Lazy.t -> int -> int = <fun>
# let rec g' = lazy (f g');;
val g' : (int -> int) Lazy.t = <lazy>
# let g = Lazy.force g';;
val g : int -> int = <fun>
# g 10;;
- : int = 3628800

Lukasz Stafiniak wrote:

> While we are at it, what is the best way to convert a "straight" list
> into a cyclic list?
> 
> i.e. convert
> 
> let l = a::b::[]
> 
> into
> 
> let rec l = a::b::l
> 
> (for arbitrary length lists). (The answer I recall from the archives
> was using Obj.magic to mutate the [] in the original list).

Obj.magic is not part of the OCaml language :-)

Again, you can do that just fine using lazy lists instead of lists:

type 'a lazylist = 'a lazylist_content Lazy.t
and 'a lazylist_content = Nil | Cons of 'a * 'a lazylist

Hope this helps,

- Xavier Leroy