(* Closures in F# are similar to those of other langauges with automatic memory management. They are typed. *) open System // accumulator: let make_accumulator init = let mutable x = init fun y -> x <- x + y x // make_accumulator let a1 = make_accumulator 0 let a2 = make_accumulator 0 printfn "%d" (a1 2); printfn "%d" (a1 2); printfn "%d" (a1 2); printfn "%d" (a2 2); /////// bank accounts let make_account init = let mutable balance = init let inquiry = fun x -> printfn "balance = %d" balance; let withdraw amt = if amt>0 && amt0 then balance <- balance + amt; else printfn "invalid transaction" let public_interface req = match req with | "inquiry" -> inquiry | "deposit" -> deposit | "withdraw" -> withdraw | _ -> printfn "invalid request"; fun x -> () public_interface;; // body of make_account returns the public interface // make_account // Notice that, unlike in the untyped Python version, here the public_interface // function has to always return something of the same type. Thus the // inquiry function also takes an argument and even the default "invalid // request" case has to return a function. The type returned by // public_interface is int -> unit. You can think of unit as "void". The // special value () is of type unit. // convenient ways to call methods let withdraw acc amt = (acc "withdraw" amt); let deposit acc amt = (acc "deposit" amt); let inquiry acc = (acc "inquiry" 0); let ac1 = make_account 1000 let ac2 = make_account 2000 withdraw ac1 500 deposit ac2 200 withdraw ac2 100 inquiry ac1 inquiry ac2;; // #load "closures.fsx"; open Closures;;