Advertisement
evluc

Untitled

Apr 20th, 2015
2,963
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. datatype intSeq = Cons of int * (unit -> intSeq);
  2.  
  3. (* ---------------------------------------------------- *)
  4. (* Seqnent of ones ... *)
  5. (* val oneSeq = fn : unit -> intSeq *)
  6. fun oneSeq () = Cons(1, oneSeq)
  7.  
  8. (* Sequent of natural numbers *)
  9. (* val numsSeq = fn : int -> unit -> intSeq *)
  10. fun numsSeq n = fn () => Cons(n, numsSeq(n+1));
  11. val natSeq = numsSeq 0;
  12.  
  13. fun fSeq n k = fn () => Cons(n, fSeq (n*k) k);
  14.  
  15. (* val taken = fn : intSeq * int -> int list *)
  16. fun taken (xq, 0)         = []
  17.   | taken (Cons(x,xf), n) = x :: taken (xf (), n-1);
  18.  
  19. (*
  20. - taken (oneSeq(),5);
  21. val it = [1,1,1,1,1] : int list
  22. - taken (numsSeq 8 (),5);
  23. val it = [8,9,10,11,12] : int list
  24. - taken (natSeq (),5);
  25. val it = [0,1,2,3,4] : int list
  26. *)
  27.  
  28.  
  29. (* ---------------------------------------------------- *)
  30. (* Force the evaluation of the tail of the sequent *)
  31. fun force(f) = f()
  32.  
  33. (* we can write our own hd and tl functions directly.
  34.    Note: we always force the first element of our
  35.    infinite sequent.
  36.  *)
  37.  
  38. fun hd (Cons(x,xf)) = x;
  39. fun tl (Cons(x,xf)) = force (xf);
  40.  
  41. (* Note: we are not that lazy, since we always expose the first
  42.    element of the sequence. *)
  43.  
  44. fun add (Cons(x,xf),Cons(y,yf)): intSeq =
  45.     Cons(x+y, fn () => add (force xf, force yf))
  46.    
  47. (*
  48. - taken (add (natSeq (), natSeq ()), 10);
  49. val it = [0,2,4,6,8,10,12,14,16,18] : int list
  50. -
  51. *)
  52.  
  53. val FibStream =
  54.     let
  55.     fun fib a b = Cons(a, (fn () => fib b (a+b)))
  56.     in
  57.     fib 0 1
  58.     end
  59.  
  60. (* can also define fibs like this *)
  61. fun fibs (): intSeq =
  62.     Cons(0, fn () => Cons(1, fn () => add(force fibs,tl((force fibs)))))
  63.  
  64. (* 
  65.  
  66. - taken (FibStream, 10);
  67. val it = [0,1,1,2,3,5,8,13,21,34] : int list
  68.  
  69. *)
  70.  
  71.  
  72. (* mapSeq: (int -> int) -> intSeq -> intSeq *)
  73. fun mapSeq f (Cons(x,xs)) =
  74.     Cons( f x, fn () => mapSeq f (force xs) )
  75.  
  76.  
  77. (* filterSeq: (int -> bool) -> intSeq -> intSeq *)
  78. fun filterSeq f (Cons (x, xs)) =
  79.     if (f x) then Cons (x, fn () => filterSeq f (force xs))
  80.     else filterSeq f (force xs)
  81.  
  82.  
  83. val even = filterSeq (fn x => (x mod 2) = 0) (force natSeq)
  84. val odd = filterSeq (fn x => (x mod 2) = 1) (force natSeq)
  85.  
  86. (*
  87. - taken (even,  10);
  88. val it = [0,2,4,6,8,10,12,14,16,18] : int list
  89. - taken (odd,  10);
  90. val it = [1,3,5,7,9,11,13,15,17,19] : int list
  91. -
  92. *)
  93.  
  94. (* intTreeFrom, creates full infinite binary trees *)
  95. datatype intTree = Node of (unit -> intTree) * int * (unit -> intTree)
  96.  
  97. fun intTreeFrom (k:int) : intTree =
  98.     Node (fn () => intTreeFrom (2*k), k, fn () => intTreeFrom (2*k+1))
  99.      
  100.  
  101. (* Below is Friedman's stream assignment, Catalan numbers *)
  102.  
  103. datatype realSeq = Cons of real * (unit -> realSeq)
  104.                      
  105. (* Calculate all the catalan numbers up to C_i *)
  106. fun catalan (i : int) : int =
  107.     let
  108.     fun next_cat (n, prev_cat) = ((2.0 * (2.0 * (Real.fromInt n) + 1.0)) / ((Real.fromInt n) + 2.0)) * prev_cat
  109.     val list_to_i = List.tabulate (i, (fn x => x))
  110.     in
  111.     Real.floor (foldl next_cat 1.0 list_to_i)
  112.     end
  113.  
  114. (* Calculate the coefficient of the ith catalan number, and a lazy stream of future coefficients *)
  115. fun helperSeq (i : int) : realSeq =
  116.     let
  117.     val x = (2.0 * (2.0 * (Real.fromInt i) + 1.0)) / ((Real.fromInt i) + 2.0)
  118.     val xs = fn () => helperSeq (i + 1)
  119.     in
  120.     Cons (x, xs)
  121.     end
  122.  
  123. (* Returns the first catalan number, and a lazy stream to evaluate the rest *)
  124. val catalanStream =
  125.     let
  126.     (*  The idea here is to pass in the previous catalan number, and the stream of coefficients to
  127.         multiply future catalan numbers by. *)
  128.     fun cat prev_cat seq =
  129.         let
  130.         val Cons(coef, seq') = seq (* Grab the next value out of the stream of coefficients *)
  131.         in
  132.         (* Calculate the current catalan number, and pause computation with the sequence of coefs advanced *)
  133.         Cons(coef * prev_cat, fn () => cat (coef * prev_cat) (seq' ()))
  134.         end
  135.     in
  136.     Cons(1.0, fn () => cat 1.0 (helperSeq 0)) (* Tack on C_0 at the beginning, and stage computation of the rest of the stream *)
  137.     end
  138.  
  139. (* -------------------------------------------------------------*)
  140. (* Question 4 : Streams  and lazy programming (30 points)       *)
  141. (* -------------------------------------------------------------*)
  142.  
  143. (* Suspended computation *)
  144. datatype 'a stream' = Susp of unit -> 'a stream
  145.  
  146. (* Lazy stream construction *)
  147. and 'a stream = Empty | Cons of 'a * 'a stream'
  148.  
  149. (* Lazy stream construction and exposure *)
  150. fun delay (d) = Susp(d)
  151. fun force (Susp(d)) = d ()
  152.  
  153. (* Eager stream construction *)
  154. val empty = Susp (fn () => Empty)
  155. fun cons (x, s) = Susp (fn () => Cons (x, s))
  156.  
  157.  
  158. (* smap: ('a -> 'b) -> 'a stream' -> 'b stream' *)
  159. fun smap f s =
  160.     let
  161.     fun mapStr (s) = mapStr'(force s)    
  162.     and mapStr'(Cons(x, s)) = delay(fn () => Cons((f x), mapStr(s)))
  163.       | mapStr' Empty = empty
  164.     in
  165.     mapStr(s)
  166.     end
  167.  
  168. (* Appending two streams
  169.  
  170.  append  : 'a stream' * 'a stream' -> 'a stream'
  171.  append' : 'a stream * 'a stream' -> 'a stream'
  172.  
  173.  *)
  174. fun append (s,s') = append'(force s, s')
  175. and append' (Empty, yq) = yq
  176.   | append' (Cons(x,xf),yq) =
  177.     delay(fn () => Cons(x, append(xf, yq)));
  178.  
  179. (* Inspect a stream up to n elements
  180.    take : int -> 'a stream' susp -> 'a list
  181.    take': int -> 'a stream' -> 'a list
  182.  *)
  183. fun take 0 s = []
  184.   | take n (s) = take' n (force s)
  185. and take' 0 s = []
  186.   | take' n (Cons(x,xs)) = x::(take (n-1) xs)
  187.  
  188.  
  189. (* -------------------------------------------------------------*)
  190. (* Q 4.1 Interleave (10 points)                                 *)
  191. (* -------------------------------------------------------------*)
  192. (* interleave: 'a -> 'a list -> 'a list stream' *)
  193.  
  194. fun interleave x [] =
  195.     cons([x], empty)
  196.   | interleave x (y::ys) =
  197.     delay(fn () => Cons(x::y::ys, smap (fn l => y::l) (interleave x ys)))
  198.  
  199.  
  200. (* -------------------------------------------------------------*)
  201. (* Q 4.2 Flatten a stream (10 points)                           *)
  202. (* -------------------------------------------------------------*)
  203.  
  204. (* flattenS: ('a stream') stream' -> 'a stream'
  205.    flattenS': 'a stream' stream -> 'a stream'
  206.  
  207.  *)
  208.  
  209. fun flattenS s = flattenS' (force s)
  210. and flattenS' (Empty) = empty
  211.   | flattenS' (Cons(s1,s)) = append(s1, flattenS s)
  212.  
  213.  
  214. (* -------------------------------------------------------------*)
  215. (* Q 4.3 Permutations (10 points)                               *)
  216. (* -------------------------------------------------------------*)
  217. (* permute: 'a list -> 'a list stream' *)
  218. fun permute [] = cons([], empty)
  219.   | permute (x::xs) = flattenS (smap (fn l => interleave x l) (permute xs))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement