From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 5E903BC37 for ; Wed, 28 Oct 2009 17:52:28 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoMCAF0T6ErUGyoGkWdsb2JhbACbPgEBAQEJCwoHEwO+eYQ/BA X-IronPort-AV: E=Sophos;i="4.44,640,1249250400"; d="scan'208";a="39112340" Received: from smtp6-g21.free.fr ([212.27.42.6]) by mail1-smtp-roc.national.inria.fr with ESMTP; 28 Oct 2009 17:52:27 +0100 Received: from smtp6-g21.free.fr (localhost [127.0.0.1]) by smtp6-g21.free.fr (Postfix) with ESMTP id 275F8E081FD; Wed, 28 Oct 2009 17:52:21 +0100 (CET) Received: from [192.168.1.3] (che78-2-82-237-71-191.fbx.proxad.net [82.237.71.191]) by smtp6-g21.free.fr (Postfix) with ESMTP id E293EE080F0; Wed, 28 Oct 2009 17:52:18 +0100 (CET) Message-ID: <4AE876C2.8050707@inria.fr> Date: Wed, 28 Oct 2009 17:52:18 +0100 From: Xavier Leroy User-Agent: Thunderbird 2.0.0.4 (X11/20070620) MIME-Version: 1.0 To: mathias@kende.fr Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] forbidden construct as right hand side of "let rec" References: <1256250121.4178.37.camel@MATHIAS-ENS> In-Reply-To: <1256250121.4178.37.camel@MATHIAS-ENS> X-Enigmail-Version: 0.95.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; compiler:01 ocaml:01 rec':01 val:01 val:01 lukasz:01 ocaml:01 mathias:98 wrote:01 wrote:01 rec:01 rec:01 caml-list:01 cyclic:01 int:01 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 = # let rec g' = lazy (f g');; val g' : (int -> int) Lazy.t = # let g = Lazy.force g';; val g : int -> int = # 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