Advertisement
Guest User

Untitled

a guest
Nov 19th, 2016
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 2.25 KB | None | 0 0
  1. open Batteries
  2.  
  3. class virtual ['i] number = object(self : 'a)
  4.   method virtual succ : 'a
  5.   method virtual pred : 'a option
  6.   method virtual get_data : 'i
  7. end
  8.  
  9.  
  10.  
  11. type 'i lazy_number_data =
  12.   | Number of 'i number
  13.   | Zero
  14.   | Succ of 'i lazy_number_data
  15.   | Sum of 'i lazy_number_data * 'i lazy_number_data
  16.  
  17. class ['i] lazy_number data0 = object
  18.   inherit (['i] number)
  19.   val data = data0
  20.   method succ = {< data = Succ data >}
  21.   method pred =
  22.     let rec aux = function
  23.       | Number x -> x#pred |> Option.map (fun t -> Number t)
  24.       | Zero -> None
  25.       | Succ x -> Some x
  26.       | Sum (x1, x2) -> begin
  27.           match aux x1 with
  28.           | None -> aux x2
  29.           | Some x1' -> Some (Sum (x1', x2))
  30.         end
  31.     in
  32.     match aux data with
  33.     | None -> None
  34.     | Some data' -> Some {< data = data' >}
  35.   method get_data = `Lazy data
  36. end
  37.  
  38. let lazy_number_data_of_number x =
  39.   match x#get_data with
  40.   | `Lazy x' -> x'
  41.   | _ -> Number x
  42.  
  43. let lazy_sum x y =
  44.   let lazy_x = lazy_number_data_of_number x in
  45.   let lazy_y = lazy_number_data_of_number y in
  46.   new lazy_number (Sum (lazy_x, lazy_y))
  47.  
  48.  
  49.  
  50. type unary_number_data =
  51.   | O
  52.   | S of unary_number_data
  53.  
  54. class ['i] unary_number data0 = object
  55.   inherit (['i] number)
  56.   val data = data0
  57.   method succ = {< data = S data >}
  58.   method pred =
  59.     match data with
  60.     | O -> None
  61.     | S data' -> Some {< data = data' >}
  62.   method get_data = `Unary data
  63. end
  64.  
  65. let rec unary_number_data_of_number x =
  66.   match x#get_data with
  67.   | `Unary x' -> x'
  68.   | _ -> begin
  69.       let rec aux t =
  70.         match t#pred with
  71.         | None -> O
  72.         | Some t' -> S (aux t')
  73.       in
  74.       aux x
  75.     end
  76.  
  77. let unary_sum x y =
  78.   let unary_sum_number_unary_number_data x0 y0 =
  79.     let rec aux x =
  80.       match x#pred with
  81.       | None -> y0
  82.       | Some x' -> S (aux x')
  83.     in
  84.     aux x0
  85.   in
  86.   match x#get_data, y#get_data with
  87.   | `Unary x', _ -> unary_sum_number_unary_number_data y x'
  88.   | _, `Unary y' -> unary_sum_number_unary_number_data x y'
  89.   | _ -> unary_sum_number_unary_number_data x (unary_number_data_of_number y)
  90.  
  91. let _ =
  92.   let one = new unary_number (S O) in
  93.   let two = new lazy_number (Sum ((Succ Zero), (Succ Zero))) in
  94.   let three = lazy_sum one two in
  95.   ()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement