From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 6FBE6BC68 for ; Sun, 1 Oct 2006 02:23:16 +0200 (CEST) Received: from ptb-relay02.plus.net (ptb-relay02.plus.net [212.159.14.213]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id k910NFTW010132 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 1 Oct 2006 02:23:16 +0200 Received: from [80.229.56.224] (helo=[10.0.0.5]) by ptb-relay02.plus.net with esmtp (Exim) id 1GTp6l-0005Ef-2X for caml-list@yquem.inria.fr; Sun, 01 Oct 2006 01:23:03 +0100 From: Jon Harrop Organization: Flying Frog Consultancy Ltd. To: caml-list@yquem.inria.fr Subject: Re: [Caml-list] More problems with memoization Date: Sun, 1 Oct 2006 01:23:48 +0100 User-Agent: KMail/1.9.4 References: <20060930200125.bjpzgnh7kkkogkgk@webmail.etu.upmc.fr> In-Reply-To: <20060930200125.bjpzgnh7kkkogkgk@webmail.etu.upmc.fr> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200610010123.48846.jon@ffconsultancy.com> X-Miltered: at concorde with ID 451F0A73.001 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; memoization:01 pons:01 memoized:01 fib:01 fib:01 val:01 val:01 recursion:01 higher-order:01 recursive:01 combinator:01 higher-order:01 memoization:01 memoize:01 hashtbl:01 On Saturday 30 September 2006 19:01, Diego Olivier FERNANDEZ PONS wrote: > I wrote the following (classical) memoized code for the fibonacci > function and I have been unsuccessfully trying to generalize it with a > higher order function. > > let rec fib = function > > | 0 -> 0 > | 1 -> 1 > | n -> fib_mem (n - 1) + fib_mem (n - 2) > > and fib_mem = > let table = ref [] in > function n -> > try > List.assoc n !table > with Not_found -> > let f_n = fib n in > table := (n, f_n) :: !table; > f_n > > # val fib : int -> int = > # val fib_mem : int -> int = > > It works: fib 35 answers instantaneously. > > Now I want to achieve the same result with a higher order function > [make_memo] and apply it to fib I believe you want to "untie the knot" of recursion, creating an higher-order, auxiliary fibonacci function fib_aux that accepts the recursive call as an argument: # let rec fib_aux fib = function | 0 | 1 as n -> n | n -> fib(n - 1) + fib(n - 2);; val fib_aux : (int -> int) -> int -> int = You can recover the ordinary fibonacci function using the Y combinator: # let rec fib n = fib_aux fib n;; val fib : int -> int = You can write a higher-order memoization function that accepts an argument with the type of fib_aux: # let memoize f = let m = Hashtbl.create 0 in let rec f' n = try Hashtbl.find m n with Not_found -> let x = f f' n in Hashtbl.replace m n x; x in f';; val memoize : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = Now you can memoize recursive functions easily: # memoize fib_aux 35;; - : int = 9227465 -- Dr Jon D Harrop, Flying Frog Consultancy Ltd. Objective CAML for Scientists http://www.ffconsultancy.com/products/ocaml_for_scientists