Guest User

Untitled

a guest
Jul 16th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 3.22 KB | None | 0 0
  1. structure Lazy =
  2. struct
  3. datatype 'a t_ = T of unit -> 'a
  4.                | V of 'a
  5.                | E of exn
  6. withtype 'a t = 'a t_ ref
  7.  
  8. fun lazy t = ref (T t)
  9. fun eager v = ref (V v)
  10. fun force p =
  11.     case !p of
  12.       V v => v
  13.     | E e => raise e
  14.     | T t =>
  15.       let
  16.         val v = t ()
  17.       in
  18.         p := V v ; v
  19.       end
  20.       handle e => (p := E e ; raise e)
  21. fun delay t = lazy (fn _ => force (t ()))
  22.  
  23. fun thunk p () = force p
  24. fun memoise t = thunk (lazy t)
  25.  
  26. exception Undefined
  27. val undefined = lazy (fn _ => raise Undefined)
  28. end
  29.  
  30. type 'a lazy = 'a Lazy.t
  31. val F = Lazy.force
  32. val E = Lazy.eager
  33. val L = Lazy.lazy
  34. val D = Lazy.delay
  35. val undefined = Lazy.undefined
  36.  
  37. infixr $
  38. fun f $ a = f a
  39. fun fst (x, _) = x
  40. fun snd (_, x) = x
  41.  
  42. datatype 'a stream = Stream of ('a * 'a stream lazy)
  43.  
  44. fun take 0 _ = nil
  45.   | take n s =
  46.     let
  47.       val Stream (x, s') = F s
  48.     in
  49.       x :: take (n - 1) s'
  50.     end
  51.  
  52. fun map f s =
  53.     L (fn _ =>
  54.           let
  55.             val Stream (x, s') = F s
  56.           in
  57.             Stream (f x, map f s')
  58.           end
  59.       )
  60.  
  61. fun scan f b s =
  62.     L (fn _ =>
  63.           let
  64.             val Stream (x, s') = F s
  65.             val y = f (x, b)
  66.           in
  67.             Stream (y, scan f y s')
  68.           end
  69.       )
  70.  
  71. fun zip s t =
  72.     L (fn _ =>
  73.           let
  74.             val Stream (x, s') = F s
  75.             val Stream (y, t') = F t
  76.           in
  77.             Stream ((x, y), zip s' t')
  78.           end
  79.       )
  80.  
  81. val nat =
  82.     let
  83.       fun loop n = L (fn _ => Stream (n, loop $ n + 1))
  84.     in
  85.       loop 1
  86.     end
  87. fun repeat n = L (fn _ => Stream (n, repeat n))
  88. fun cons x s = L (fn _ => Stream (x, s))
  89.  
  90. type ('s, 'a) rstate = 's lazy -> 'a lazy * 's lazy
  91. infix >>=
  92.  
  93. val return : ('a lazy -> ('s, 'a) rstate) =
  94.  fn x => fn s => (x, s)
  95.  
  96. val op>>= : ('s, 'a) rstate * ('a lazy -> ('s, 'b) rstate) -> ('s, 'b) rstate =
  97.  fn (m, k) =>
  98.  fn s =>
  99.     let
  100.       val r = ref undefined
  101.       val s' = L (fn _ => F $ !r)
  102.       val (x, s'') = m s'
  103.       val t =
  104.           L (fn _ =>
  105.                 let
  106.                   val (y, s') = k x s
  107.                 in
  108.                   r := s' ; y
  109.                 end)
  110.       val s'' =
  111.           D (fn _ => (F t ; s''))
  112.       val y =
  113.           D (fn _ => F t)
  114.     in
  115.       (y, s'')
  116.     end
  117.  
  118. val get : ('s, 's) rstate =
  119.  fn s => (s, s)
  120.  
  121. val put : 's lazy -> ('s, unit) rstate =
  122.  fn s => fn _ => (E (), s)
  123.  
  124. val modify =
  125.  fn f => fn s => (E (), f s)
  126.  
  127. val yield : 'a -> ('a stream, unit) rstate =
  128.  fn x =>
  129.  fn s =>
  130.     (E (), cons x s)
  131.  
  132. fun fiba x y =
  133.     do yield x
  134.      ; fiba y (x + y)
  135.     end
  136.  
  137. fun cumsum s =
  138.     let
  139.       fun loop n s =
  140.           cons n $
  141.                D (fn _ =>
  142.                      let
  143.                        val Stream (x, s') = F s
  144.                      in
  145.                        loop (n + x) s'
  146.                      end
  147.                  )
  148.     in
  149.       loop 0 s
  150.     end
  151.  
  152. val fibb =
  153.     do fibs <- get
  154.      ; modify cumsum
  155.      ; put $ cons 1 fibs
  156.      ; return fibs
  157.     end
  158.  
  159. val fact =
  160.     do f <- get
  161.      ; modify (map op* o zip nat)
  162.      ; put $ cons 1 f
  163.      ; return f
  164.     end
  165.  
  166. ; take 10 $ snd $ fiba 0 1 undefined ;
  167. ; take 10 $ snd $ fibb undefined ;
Add Comment
Please, Sign In to add comment