From: Jim Pryor Date: Sun, 29 May 2011 17:54:42 +0000 (-0400) Subject: Merge branch 'pryor' X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=commitdiff_plain;h=67ed83b1ad44c7590cf7d7c1ec3a079bc5140a61;hp=9b5f91f462e9f64944ce2aa95ab3f8d30371a469 Merge branch 'pryor' --- diff --git a/code/monads.ml b/code/monads.ml index 10ef808e..d8725937 100644 --- a/code/monads.ml +++ b/code/monads.ml @@ -38,7 +38,7 @@ * making their implementations private. The interpreter won't let * let you freely interchange the `'a Reader_monad.m`s defined below * with `Reader_monad.env -> 'a`. The code in this library can see that - * those are equivalent, but code outside the library can't. Instead, you'll + * those are equivalent, but code outside the library can't. Instead, you'll * have to use operations like `run` to convert the abstract monadic types * to types whose internals you have free access to. * @@ -115,7 +115,7 @@ module Monad = struct * (Catch) plus (unit a) v === unit a * (Distrib) plus u v >>= f === plus (u >>= f) (v >>= f) * When no natural zero is available, use `let zero () = Util.undef`. - * The Make functor automatically detects for zero >>= ..., and + * The Make functor automatically detects for zero >>= ..., and * plus zero _, plus _ zero; it also substitutes zero for pattern-match failures. *) val zero : unit -> ('x,'a) m @@ -339,10 +339,8 @@ module List_monad : sig (* note that second argument is an 'a list, not the more abstract 'a m *) (* type is ('a -> 'b W) -> 'a list -> 'b list W == 'b listT(W) *) val distribute : ('a -> ('x,'b) Wrapped.m) -> 'a list -> ('x,'b) m -(* TODO - val permute : 'a m -> 'a m m - val select : 'a m -> ('a * 'a m) m -*) + val permute : ('x,'a) m -> ('x,('x,'a) m) m + val select : ('x,'a) m -> ('x,('a * ('x,'a) m)) m val expose : ('x,'a) m -> ('x,'a list) Wrapped.m end end = struct @@ -378,7 +376,7 @@ end = struct | [] -> zero () | x::xs -> plus (unit (x, xs)) (select xs >>= fun (x', xs') -> unit (x', x :: xs')) module T(Wrapped : Monad.S) = struct - (* Wrapped.sequence ms === + (* Wrapped.sequence ms === let plus1 u v = Wrapped.bind u (fun x -> Wrapped.bind v (fun xs -> @@ -410,10 +408,29 @@ end = struct Wrapped.bind v (fun vs -> Wrapped.unit (Base.plus us vs))) end) -(* - let permute : 'a m -> 'a m m - let select : 'a m -> ('a * 'a m) m -*) + + (* insert 3 {[1;2]} ~~> {[ {[3;1;2]}; {[1;3;2]}; {[1;2;3]} ]} *) + let rec insert a u = + plus + (unit (Wrapped.bind u (fun us -> Wrapped.unit (a :: us)))) + (Wrapped.bind u (fun us -> match us with + | [] -> zero () + | x::xs -> (insert a (Wrapped.unit xs)) >>= fun v -> unit (Wrapped.bind v (fun vs -> Wrapped.unit (x :: vs))))) + + (* select {[1;2;3]} ~~> {[ (1,{[2;3]}); (2,{[1;3]}), (3;{[1;2]}) ]} *) + let rec select u = + Wrapped.bind u (fun us -> match us with + | [] -> zero () + | x::xs -> plus (unit (x, Wrapped.unit xs)) + (select (Wrapped.unit xs) >>= fun (x', xs') -> unit (x', Wrapped.bind xs' (fun ys -> Wrapped.unit (x :: ys))))) + + (* permute {[1;2;3]} ~~> {[ {[1;2;3]}; {[2;1;3]}; {[2;3;1]}; {[1;3;2]}; {[3;1;2]}; {[3;2;1]} ]} *) + + let rec permute u = + Wrapped.bind u (fun us -> match us with + | [] -> unit (zero ()) + | x::xs -> permute (Wrapped.unit xs) >>= (fun v -> insert x v)) + let expose u = u end end