cannam@95
|
1 (*
|
cannam@95
|
2 * Copyright (c) 1997-1999 Massachusetts Institute of Technology
|
cannam@95
|
3 * Copyright (c) 2003, 2007-11 Matteo Frigo
|
cannam@95
|
4 * Copyright (c) 2003, 2007-11 Massachusetts Institute of Technology
|
cannam@95
|
5 *
|
cannam@95
|
6 * This program is free software; you can redistribute it and/or modify
|
cannam@95
|
7 * it under the terms of the GNU General Public License as published by
|
cannam@95
|
8 * the Free Software Foundation; either version 2 of the License, or
|
cannam@95
|
9 * (at your option) any later version.
|
cannam@95
|
10 *
|
cannam@95
|
11 * This program is distributed in the hope that it will be useful,
|
cannam@95
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
cannam@95
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
cannam@95
|
14 * GNU General Public License for more details.
|
cannam@95
|
15 *
|
cannam@95
|
16 * You should have received a copy of the GNU General Public License
|
cannam@95
|
17 * along with this program; if not, write to the Free Software
|
cannam@95
|
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
cannam@95
|
19 *
|
cannam@95
|
20 *)
|
cannam@95
|
21
|
cannam@95
|
22 (*************************************************************
|
cannam@95
|
23 * Monads
|
cannam@95
|
24 *************************************************************)
|
cannam@95
|
25
|
cannam@95
|
26 (*
|
cannam@95
|
27 * Phil Wadler has many well written papers about monads. See
|
cannam@95
|
28 * http://cm.bell-labs.com/cm/cs/who/wadler/
|
cannam@95
|
29 *)
|
cannam@95
|
30 (* vanilla state monad *)
|
cannam@95
|
31 module StateMonad = struct
|
cannam@95
|
32 let returnM x = fun s -> (x, s)
|
cannam@95
|
33
|
cannam@95
|
34 let (>>=) = fun m k ->
|
cannam@95
|
35 fun s ->
|
cannam@95
|
36 let (a', s') = m s
|
cannam@95
|
37 in let (a'', s'') = k a' s'
|
cannam@95
|
38 in (a'', s'')
|
cannam@95
|
39
|
cannam@95
|
40 let (>>) = fun m k ->
|
cannam@95
|
41 m >>= fun _ -> k
|
cannam@95
|
42
|
cannam@95
|
43 let rec mapM f = function
|
cannam@95
|
44 [] -> returnM []
|
cannam@95
|
45 | a :: b ->
|
cannam@95
|
46 f a >>= fun a' ->
|
cannam@95
|
47 mapM f b >>= fun b' ->
|
cannam@95
|
48 returnM (a' :: b')
|
cannam@95
|
49
|
cannam@95
|
50 let runM m x initial_state =
|
cannam@95
|
51 let (a, _) = m x initial_state
|
cannam@95
|
52 in a
|
cannam@95
|
53
|
cannam@95
|
54 let fetchState =
|
cannam@95
|
55 fun s -> s, s
|
cannam@95
|
56
|
cannam@95
|
57 let storeState newState =
|
cannam@95
|
58 fun _ -> (), newState
|
cannam@95
|
59 end
|
cannam@95
|
60
|
cannam@95
|
61 (* monad with built-in memoizing capabilities *)
|
cannam@95
|
62 module MemoMonad =
|
cannam@95
|
63 struct
|
cannam@95
|
64 open StateMonad
|
cannam@95
|
65
|
cannam@95
|
66 let memoizing lookupM insertM f k =
|
cannam@95
|
67 lookupM k >>= fun vMaybe ->
|
cannam@95
|
68 match vMaybe with
|
cannam@95
|
69 Some value -> returnM value
|
cannam@95
|
70 | None ->
|
cannam@95
|
71 f k >>= fun value ->
|
cannam@95
|
72 insertM k value >> returnM value
|
cannam@95
|
73
|
cannam@95
|
74 let runM initial_state m x = StateMonad.runM m x initial_state
|
cannam@95
|
75 end
|