|
| 1 | +(* I. Introduction *) |
| 2 | + |
| 3 | +type nat = Zero | Succ of nat |
| 4 | + |
| 5 | +type 'a stream = ('a cell) Lazy.t and 'a cell = Cell of 'a * 'a stream |
| 6 | + |
| 7 | +let rec from : nat -> nat stream = fun n -> lazy (Cell (n, from (Succ n))) |
| 8 | + |
| 9 | +let naturals = from Zero |
| 10 | + |
| 11 | +let rec nth : nat -> 'a stream -> 'a = fun n s -> |
| 12 | + let Cell (hd, tl) = Lazy.force s in |
| 13 | + match n with |
| 14 | + | Zero -> hd |
| 15 | + | Succ m -> nth m tl |
| 16 | + |
| 17 | +type 'a stream = { |
| 18 | + Head : 'a; |
| 19 | + Tail : 'a stream; |
| 20 | +} |
| 21 | + |
| 22 | +let corec from : nat -> nat stream with |
| 23 | + | (.. n)#Head -> Zero |
| 24 | + | (.. n)#Tail -> from (Succ n) |
| 25 | + |
| 26 | +let rec nth n s = match n with |
| 27 | + | Zero -> s#Head |
| 28 | + | Succ m -> nth m s#Tail |
| 29 | + |
| 30 | + |
| 31 | +let corec map2 : type a b c. (a -> b -> c) -> a stream -> b stream -> c stream with |
| 32 | + | (.. f s1 s2)#Head -> f s1#Head s2#Head |
| 33 | + | (.. f s1 s2)#Tail -> map2 f s1#Tail s2#Tail |
| 34 | + |
| 35 | +(* III. Constructions avancées du filtrage par comotifs *) |
| 36 | + |
| 37 | +let corec fib : int stream with |
| 38 | + | ..#Head -> 0 |
| 39 | + | ..#Tail : int stream with |
| 40 | + | ..#Tail#Head -> 1 |
| 41 | + | ..#Tail#Tail -> map2 ( + ) fib fib#Tail |
| 42 | + |
| 43 | +let corec lazy fib : int stream with |
| 44 | + | ..#Head -> 0 |
| 45 | + | ..#Tail : int stream with |
| 46 | + | ..#Tail#Head -> 1 |
| 47 | + | ..#Tail#Tail -> map2 ( + ) fib fib#Tail |
| 48 | + |
| 49 | +let corec cycle : nat -> nat stream with |
| 50 | + | (.. n)#Head -> n |
| 51 | + | (.. Zero)#Tail -> cycle (Succ (Succ (Succ Zero))) |
| 52 | + | (.. (Succ m))#Tail -> cycle m |
| 53 | + |
| 54 | +type zero = Z and 'a succ = S |
| 55 | + |
| 56 | +type 'a fuel = |
| 57 | + | Dry : zero fuel |
| 58 | + | More : 'a fuel -> ( 'a succ) fuel |
| 59 | + |
| 60 | +type ('a,'b) bounded_iterator = { |
| 61 | + GetVal : 'a; |
| 62 | + Next : ('a,'b) bounded_iterator <- ('a, 'b succ) bounded_iterator; |
| 63 | +} |
| 64 | + |
| 65 | +module type Seq = sig |
| 66 | + type 'a t |
| 67 | + val head : 'a t -> 'a |
| 68 | + val tail : 'a t -> 'a t |
| 69 | +end |
| 70 | + |
| 71 | +module MkIterator (S : Seq) = struct |
| 72 | + let corec wrap : type a b.a S.t -> b fuel -> (a, b) bounded_iterator with |
| 73 | + | (.. l n)#GetVal -> S.head l |
| 74 | + | (.. l (More n))#Next -> wrap (S.tail l) n |
| 75 | +end |
| 76 | + |
| 77 | +(* IV. Destructeurs de premier ordre et première classe *) |
| 78 | + |
| 79 | +type _loc = {name: string; x : int; y : int} |
| 80 | + |
| 81 | +let select_name lc = lc.name and update_name s lc = {lc with name = s} |
| 82 | +let select_x lc = lc.x and update_x b lc = {lc with x = b} |
| 83 | +let select_y lc = lc.y and update_y n lc = {lc with y = n} |
| 84 | + |
| 85 | +type loc = {Name : string; X : int; Y: int} |
| 86 | + |
| 87 | +let select (d : 'a loc_obs) (Loc {dispatch} : loc) : 'a = dispatch d |
| 88 | + |
| 89 | +type (_,_) eq = Eq : ('a,'a) eq |
| 90 | + |
| 91 | +let eq_loc : type a b. a loc_obs * b loc_obs -> ((a,b) eq) option = function |
| 92 | + | (Name, Name) -> Some Eq |
| 93 | + | (X, X) -> Some Eq |
| 94 | + | (Y, Y) -> Some Eq |
| 95 | + | _ -> None |
| 96 | + |
| 97 | +let update (type a) (d1 : a loc_obs) (x : a) (Loc {dispatch}) = |
| 98 | + let dispatch : type o. o loc_obs -> o = fun d2 -> match eq_loc (d1,d2) with |
| 99 | + | Some Eq -> x |
| 100 | + | _ -> dispatch d2 |
| 101 | + in Loc {dispatch} |
0 commit comments