Advertisement
justin_hanekom

Ocaml prelude

Jul 20th, 2016 (edited)
327
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 23.38 KB | None | 0 0
  1. open List
  2. open Printf
  3. open String
  4.  
  5. (* ----- TUPLES ----- *)
  6.  
  7. (** Returns the first component of a pair. *)
  8. let fst (a, _) = a
  9.  
  10. (** Returns the second component of pair. *)
  11. let snd (_, b) = b
  12.  
  13.  
  14. (* ----- FOLDS AND TRAVERSALS ----- *)
  15.  
  16. (**
  17.  * Left-associative fold of a list.
  18.  * This function is not tail recursive.
  19.  *
  20.  * @param fn  function to apply to  each element of the list;
  21.  *            fn is called with the accumulator and an element,
  22.  *            and must return a new accumulator
  23.  * @param acc initial accumulator value
  24.  * @param lst list of elements to be fed to f
  25.  * @result    final accumulator value created by applying f
  26.  *            to each element of xs, from the left
  27.  * @see       fold_left
  28.  *)
  29. let foldl fn acc lst = fold_left fn acc lst
  30.  
  31. (**
  32.  * Right-associative fold of a list.
  33.  * This function is tail recursive.
  34.  *
  35.  * @param fn  function to apply to each element of the list;
  36.  *            fn is called with the accumulator and an element,
  37.  *            and must return a new accumulator
  38.  * @param acc initial accumulator value
  39.  * @param lst list of elements to be fed to f
  40.  * @result    final accumulator value created by applying f
  41.  *            to each element of xs, from the right
  42.  * @see       fold_right
  43.  *)
  44. let foldr fn lst acc = fold_right fn lst acc
  45.  
  46. (**
  47.  * Maps each element of a list to a function, and combines the results.
  48.  * This function is not tail recursive.
  49.  *
  50.  * @param fn  function to apply to each element of the list
  51.  * @param lst list of elements to be fed to f
  52.  * @result    new list of the form [f l1; f l2; f l3; ...]
  53.  * @see       map
  54.  *)
  55. let map fn lst = List.map fn lst
  56.  
  57. (**
  58.  * Maps each element of a list to a function, and throws away the results.
  59.  * This function is not tail recursive.
  60.  *
  61.  * @param fn  function to apply to each element of the list
  62.  * @param lst list of elements to be fed to f
  63.  * @see       List.iter
  64.  *)
  65. let map_ fn lst = List.iter fn lst
  66.  
  67. (**
  68.  * Returns the last element of a list, which must be non-empty.
  69.  * This function is tail-recursive.
  70.  *
  71.  * @param lst list to get the last element of
  72.  * @see       first
  73.  *)
  74. let rec last lst = match lst with
  75.     | x::[] -> x
  76.     | x::xs -> last xs
  77.     | _     -> failwith "last []"
  78.  
  79. (**
  80.  * Returns all elements excepting the last of a list,
  81.  * which must be non-empty.
  82.  * This function is not tail-recursive.
  83.  *
  84.  * @param lst list from which to extract the initial elements
  85.  * @see       tail
  86.  *)
  87. let rec init lst = match lst with
  88.     | x::[] -> []
  89.     | x::xs -> x::init xs
  90.     | _     -> failwith "init []"
  91.  
  92. (**
  93.  * Left-associative fold of a list, which must be non-empty.
  94.  * The first element of the list is used as the initial accumulator value.
  95.  * This function is not tail recursive.
  96.  *
  97.  * @param fn  function to apply to each element of the list;
  98.  *            fn is called with the accumulator and an element,
  99.  *            and must return a new accumulator
  100.  * @param lst list of elements to be fed to f
  101.  * @see       foldl
  102.  * @see       fold_left
  103.  * @see       foldr'
  104.  *)
  105. let foldl' fn lst = match lst with
  106.     | x::xs -> fold_left fn x xs
  107.     | _     -> failwith "foldl' []"
  108.  
  109. (**
  110.  * Right-associative fold of a list, which must be non-empty.
  111.  * The last element of the list is used as the initial accumulator value.
  112.  * This function is tail recursive.
  113.  *
  114.  * @param fn  function to apply to each element of the list, from the right;
  115.  *            fn is called with the accumulator and an element,
  116.  *            and must return a new accumulator
  117.  * @param lst list of elements to be fed to f
  118.  * @see       foldr
  119.  * @see       fold_right
  120.  * @see       foldl'
  121.  *)
  122. let foldr' fn lst = match lst with
  123.     | _::_ -> let acc = init lst
  124.               and lst' = last lst in
  125.               fold_right fn acc lst'
  126.     | _    -> failwith "foldr' []"
  127.  
  128.  
  129. (* -----  LIST OPERATIONS ----- *)
  130.  
  131. (** Returns whether or not a list is empty. *)
  132. let null lst = match lst with
  133.     | [] -> true
  134.     | _  -> false
  135.  
  136. (** Returns the length of a list. *)
  137. let length = List.length
  138.  
  139. (** Returns the first element of a list, which must be non-empty. *)
  140. let head lst = match lst with
  141.     | _::_ -> List.hd lst
  142.     | []   -> failwith "head []"
  143.  
  144. (** Returns the remaining elements of a list, which must be non-empty. *)
  145. let tail lst = match lst with
  146.     | _::_ -> List.tl lst
  147.     | []   -> failwith "tail []"
  148.  
  149. (** Returns a copy of a list, with the elements in reverse order. *)
  150. let reverse = List.rev
  151.  
  152. (** Appends two lists .*)
  153. let (++) lst1 lst2  = append lst1 lst2
  154.  
  155. (**
  156.  * Equivalent to `(reverse lst1) ++ lst2`,
  157.  * but tail recursive and more efficient.
  158.  *
  159.  * @see reverse
  160.  * @see (++)
  161.  * @see append
  162.  *)
  163. let reverse_append lst1 lst2 = List.rev_append lst1 lst2
  164.  
  165. (**
  166.  * Concatenates a list of lists.
  167.  *
  168.  * @param xss a list of lists of the form [[]; []; ...]
  169.  *)
  170. let concat xss = List.concat xss
  171.  
  172. (**
  173.  * Returns a number of elements from the beginning of a list.
  174.  * This function is not tail-recursive.
  175.  *
  176.  * @param num number of items to take from the list
  177.  * @param lst list from which to take elements from the left of
  178.  * @see       drop
  179.  *)
  180. let rec take num lst =
  181.     if num <= 0 || (null lst)
  182.     then []
  183.     else head lst::take (num-1) (tail lst)
  184.  
  185. (**
  186.  * Drops a number of elements from the beginning of a list.
  187.  * This function is tail-recursive.
  188.  *
  189.  * @param num the number of elements to drop from the list
  190.  * @param lst list from which to drop elements
  191.  * @result    a list that is the list lst with the first num elements removed
  192.  * @see       @take
  193.  *)
  194. let rec drop num lst =
  195.     if num <= 0
  196.     then lst
  197.     else drop (num-1) (tail lst)
  198.  
  199. (**
  200.  * Returns the biggest element of a list, which must be non-empty.
  201.  *
  202.  * @see minimum
  203.  *)
  204. let maximum lst = match lst with
  205.     | _::_ -> foldl' (fun a b -> max a b) lst
  206.     | _    -> failwith "maximum []"
  207.  
  208. (**
  209.  * Returns the smallest element of a list, which must be non-empty.
  210.  *
  211.  * @see maximum
  212.  *)
  213. let minimum lst = match lst with
  214.     | _::_ -> foldl' (fun a b -> min a b) lst
  215.     | _    -> failwith "minimum []"
  216.  
  217. (**
  218.  * Returns the sum of a list of integers, which must be non-empty.
  219.  *
  220.  * @see product
  221.  *)
  222. let sum lst = match lst with
  223.     | _::_ -> foldl' (fun a b -> a+b) lst
  224.     | _    -> failwith "sum []"
  225.  
  226. (**
  227.  * Returns the product of a list of integers, which must be non-empty.
  228.  *
  229.  * @see sum
  230.  *)
  231. let product lst = match lst with
  232.     | _::_ -> foldl' (fun a b -> a*b) lst
  233.     | _    -> failwith "product []"
  234.  
  235. (**
  236.  * Returns whether or not an element is in a list.
  237.  * This function is tail-recursive.
  238.  *
  239.  * @param x   the element to search for
  240.  * @param lst the list in which to search for the element x
  241.  * @result    true if x is found in the list lst, otherwise false
  242.  *)
  243. let rec elem x lst = match lst with
  244.     | y::ys -> if x = y
  245.                then true
  246.                else elem x ys;
  247.     | []    -> false
  248.  
  249.  
  250. (* ----- NUMERIC FUNCTIONS ----- *)
  251.  
  252. (** Returns the negative of an integer. *)
  253. let negate n = (-n)
  254.  
  255. (** Returns whether or not an integer is even. *)
  256. let even n = n mod 2 = 0
  257.  
  258. (** Returns whether or not an integer is odd. *)
  259. let odd n = n mod 2 != 0
  260.  
  261. (** Returns the sign of an integer, either 1 or -1. *)
  262. let signum n = if n >= 0 then 1 else (-1)
  263.  
  264. (**
  265.  * Returns the greatest common divisor of two integers.
  266.  * This function is tail-recursive.
  267.  *)
  268. let gcd a b =
  269.    let rec gcd' a b = if b = 0
  270.                        then a
  271.                        else gcd' b (a mod b) in
  272.     gcd' (abs a) (abs b)
  273.  
  274. (** Returns the smallest positive integer that two integers divide by. *)
  275. let lcm a b = match (a, b) with
  276.     | (_, 0) -> 0
  277.     | (0, _) -> 0
  278.     | (a, b) -> (abs a*b) / (gcd a b)
  279.  
  280.  
  281. (* ----- STRING OPERATIONS ----- *)
  282.  
  283. (** Returns whether or not the string is empty. *)
  284. let is_empty str = str = ""
  285.  
  286. (** Compares two strings, ignoring case. *)
  287. let compare_ignore_case str1 str2 =
  288.     let lower1 = lowercase str1
  289.     and lower2 = lowercase str2 in
  290.     compare lower1 lower2
  291.  
  292. (**
  293.  * Returns whether or not two strings are equal, ignoring case.
  294.  *
  295.  * @see compare_ignore_case
  296.  *)
  297. let equals_ignore_case str1 str2 = compare_ignore_case str1 str2 = 0
  298.  
  299. (**
  300.  * Returns whether or not one string begins with another.
  301.  *
  302.  * @param prefix prefix to be searched for in str
  303.  * @param str    string to be tested if it begins with prefix
  304.  * @result       true if str begins with prefix, otherwise false
  305.  * @see          ends_with
  306.  *)
  307. let begins_with prefix str =
  308.     let str_len = String.length str
  309.     and pref_len = String.length prefix in
  310.     if str_len < pref_len
  311.     then false
  312.     else String.sub str 0 pref_len = prefix
  313.  
  314. (**
  315.  * Returns whether or not one string ends with another.
  316.  *
  317.  * @param suffix suffix to be searched for in str
  318.  * @param str    string to be tested if it ends with suffix
  319.  * @result       true if str ends with suffix, otherwise false
  320.  * @see          begins_with
  321.  *)
  322. let ends_with suffix str =
  323.     let str_len = String.length str
  324.     and suff_len = String.length suffix in
  325.     let pos = str_len-suff_len in
  326.     if str_len < suff_len
  327.     then false
  328.     else String.sub str pos suff_len = suffix
  329.  
  330. (**
  331.  * Returns whether or not the string contains the substring.
  332.  * This function is tail-recursive.
  333.  *
  334.  * @param substr substring to search for in the string
  335.  * @param str    string to be searched for the substring
  336.  * @result       true if the string contains the substring, otherwise false
  337.  *)
  338. let rec contains_substring substr str = match str with
  339.     | "" -> false
  340.     | _  -> if begins_with substr str
  341.             then true
  342.             else
  343.                 let str_len = (String.length str)-1 in
  344.                 let new_str = String.sub str 1 str_len in
  345.                 contains_substring substr new_str
  346.  
  347. (**
  348.  * Returns the index within the string of the character ch.
  349.  * Throws Not_found if the character does not occur in the string.
  350.  *
  351.  * @param ch  character to search for in the string
  352.  * @param str string to search for the character ch
  353.  * @result    index of the first position where ch occurs in str
  354.  * @see       index_of
  355.  * @see       last_index_of_char
  356.  *)
  357. let index_of_char ch str = index str ch
  358.  
  359. (**
  360.  * Returns the index within the string str of the string substr.
  361.  * Throws Not_found if the string does not occur in the string str.
  362.  * This function is tail-recursive.
  363.  *
  364.  * @param substr string to search for in the string str
  365.  * @param str    string to search for the string substr
  366.  * @result       index of the first position where substr occurs in str
  367.  * @see          index_of_char
  368.  * @see          last_index_of
  369.  *)
  370. let index_of substr str =
  371.     if substr = ""
  372.     then 0
  373.     else
  374.         let ch = substr.[0] in
  375.         let rec fn from =
  376.             let i = index_from str from ch in
  377.             let sub_len = String.length substr in
  378.             let found = String.sub str i sub_len in
  379.             if found = substr
  380.             then i
  381.             else fn (i+1) in
  382.         fn 0
  383.  
  384. (**
  385.  * Returns the last index within the string of the character ch.
  386.  * Throws Not_found if the character does not occur in the string.
  387.  *
  388.  * @param ch  character to search for in the string
  389.  * @param str string to search for the character ch
  390.  * @result    index of the last position where ch occurs in the string
  391.  * @see       index_of_char
  392.  * @see       last_index_of
  393.  *)
  394. let last_index_of_char ch str = rindex str ch
  395.  
  396. (**
  397.  * Returns the last index within the string str of the string substr.
  398.  * Throws Not_found if the string does not occur in the string str.
  399.  * This function is tail-recursive.
  400.  *
  401.  * @param substr string to search for in the string str
  402.  * @param str    string to search for the string substr
  403.  * @result       index of the last position where substr occurs in str
  404.  * @see          index_of
  405.  * @see          last_index_of_char
  406.  *)
  407. let last_index_of substr str =
  408.     let last_index = String.length str - 1 in
  409.     if substr = ""
  410.     then last_index
  411.     else let sub_len = String.length substr
  412.          and ch = substr.[0] in
  413.          let rec fn from =
  414.             let i = rindex_from str from ch in
  415.             let found = String.sub str i sub_len in
  416.             if found = substr
  417.             then i
  418.             else fn (i-1) in
  419.     fn last_index
  420.  
  421. (**
  422.  * Replaces all occurances of a character within
  423.  * the string with a different character.
  424.  *
  425.  * @param old character to replace in the string
  426.  * @param nu  character to replace the old character with
  427.  * @param str string in which to replace occurances of a character
  428.  * @return    new string with all occurances of old replaced by nu
  429.  *)
  430. let replace_char old nu str =
  431.     let fn ch = if ch = old
  432.                 then nu
  433.                 else ch in
  434.     String.map fn str
  435.  
  436. (**
  437.  * Splits the string str on sep and returns a list of the resulting strings.
  438.  * The separator string is not included in the returned list of strings.
  439.  * This function is tail-recursive.
  440.  *
  441.  * @param sep separator used to split the string
  442.  * @param str string that (possibly) contains one or more
  443.  *            occurances of the separator
  444.  * @result list of strings that were separated by sep
  445.  *)
  446. let split_on sep str =
  447.     let sep_len = String.length sep in
  448.     let rec fn acc str =
  449.         try let i = last_index_of sep str in
  450.             let pos = sep_len+i
  451.             and len = (String.length str)-sep_len-i in
  452.             let new_str = String.sub str 0 i
  453.             and substr = String.sub str pos len in
  454.             fn (substr::acc) new_str
  455.         with Not_found -> str::acc in
  456.     fn [] str
  457.  
  458. (**
  459.  * Joins the list of strings, interspersing the separator sep between them.
  460.  *
  461.  * @param sep  separator to put between each pair of strings
  462.  * @param strs list of strings to be joined together, with the separator sep
  463.  *             in between each pair
  464.  * @result     string concatenation of the strings in strs, separated by sep
  465.  *)
  466. let join_with sep strs = String.concat sep strs
  467.  
  468.  
  469. (** Returns the string representation of a boolean value. *)
  470. let string_of_boolean flag = match flag with
  471.     | true -> "true"
  472.     | _    -> "false"
  473.  
  474. (** Folds a list into a string. *)
  475. let string_of_list fn lst =
  476.     fold_left fn "" lst |> sprintf "[%s]"
  477.  
  478. (** Returns the string representation of a list of integers. *)
  479. let string_of_int_list lst =
  480.     let fn a n = if a = ""
  481.                  then sprintf "%d" n
  482.                  else sprintf "%s; %d" a n in
  483.     string_of_list fn lst
  484.  
  485. (** Returns the string representation of a list of strings. *)
  486. let string_of_string_list lst =
  487.     let fn a x = if a = ""
  488.                  then sprintf "\"%s\"" x
  489.                  else sprintf "%s; \"%s\"" a x in
  490.     string_of_list fn lst
  491.  
  492.  
  493. (** ----- MISCELLANEOUS FUNCTIONS ----- *)
  494.  
  495. (** Returns the identity of a value. *)
  496. let id x = x
  497.  
  498. (**
  499.  * Extracts the second element of a list,
  500.  * which must have at least two elements.
  501.  *
  502.  * @param lst the list from which to extract the second element
  503.  * @return  second element of list lst
  504.  *)
  505. let second lst = match lst with
  506.     | _::x::xs -> x
  507.     | _        -> failwith "second"
  508.  
  509.  
  510. (* ----- FUNCTION TESTS ----- *)
  511.  
  512. type boolean_test =     { test : string; expect : bool;        result : bool }
  513. type int_test =         { test : string; expect : int;         result : int }
  514. type string_test =      { test : string; expect : string;      result : string }
  515. type int_list_test =    { test : string; expect : int list;    result : int list }
  516. type string_list_test = { test : string; expect : string list; result : string list }
  517.  
  518. type test =
  519.     | BooleanTest    of boolean_test
  520.     | IntTest        of int_test
  521.     | StringTest     of string_test
  522.     | IntListTest    of int_list_test
  523.     | StringListTest of string_list_test
  524.  
  525. (** Prints the result of performing the test. *)
  526. let print_test_result x =
  527.     let print_test test expect result =
  528.         let msg = test ^ " => " ^ result in
  529.         print_endline @@ if expect = result
  530.                          then msg
  531.                          else msg ^ " *** BUT EXPECTED "^ expect in
  532.     match x with
  533.         | BooleanTest x    -> print_test x.test
  534.                                          (string_of_boolean x.expect)
  535.                                          (string_of_boolean x.result)
  536.         | IntTest x        -> print_test x.test
  537.                                          (string_of_int x.expect)
  538.                                          (string_of_int x.result)
  539.         | StringTest x     -> print_test x.test x.expect x.result
  540.         | IntListTest x    -> print_test x.test
  541.                                          (string_of_int_list x.expect)
  542.                                          (string_of_int_list x.result)
  543.         | StringListTest x -> print_test x.test
  544.                                          (string_of_string_list x.expect)
  545.                                          (string_of_string_list x.result)
  546.  
  547. let () =
  548.     let p = ["alpha"; "bravo"; "charlie"; "delta"; "echo"]
  549.     and q = ["foxtrot"; "golf"; "hotel"; "igloo"; "juliet"]
  550.     and r = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
  551.     and n = 42 in
  552.     let t = (p, q) in
  553.     let tests = [
  554.         StringListTest { test   = "fst t";
  555.                          expect = ["alpha"; "bravo"; "charlie"; "delta"; "echo"];
  556.                          result = fst t };
  557.         StringListTest { test   = "snd t";
  558.                          expect = ["foxtrot"; "golf"; "hotel"; "igloo"; "juliet"];
  559.                          result = snd t };
  560.         BooleanTest { test = "even n"; expect = true; result = even n };
  561.         BooleanTest { test = "odd n"; expect = false; result = odd n };
  562.         IntTest { test = "signum n"; expect = 1; result = signum n };
  563.         IntTest { test = "negate n"; expect = (-42); result = negate n };
  564.         IntTest { test = "gcd 42 12"; expect = 6; result = gcd 42 12 };
  565.         IntTest { test = "lcm 42 12"; expect = 84; result = lcm 42 12 };
  566.         IntTest { test = "minimum r"; expect = 1; result = minimum r };
  567.         IntTest { test = "maximum r"; expect = 10; result = maximum r };
  568.         IntTest { test = "sum r"; expect = 55; result = sum r };
  569.         IntTest { test = "product r"; expect = 3628800; result = product r };
  570.         BooleanTest { test   = "is_empty \"\"";
  571.                       expect = true;
  572.                       result = is_empty "" };
  573.         BooleanTest { test   = "is_empty \"NOT!\"";
  574.                       expect =false;
  575.                       result = is_empty "NOT!" };
  576.         IntTest { test   = "compare_ignore_case \"JESUS\" \"Jesus\"";
  577.                   expect = 0;
  578.                   result = compare_ignore_case "JESUS" "Jesus" };
  579. (*
  580.         BooleanTest { test   = "begins_with \"H\" \"Hello\"";
  581.                       expect = true;
  582.                       test   = begins_with "H" "Hello" };
  583. *)
  584.         BooleanTest { test   = "ends_with '!' \"Hello!\"";
  585.                       expect = true;
  586.                       result = ends_with "!" "Hello, World!" };
  587.         BooleanTest { test   = "contains_substring \"World\" \"Hello, World!\"";
  588.                       expect = true;
  589.                       result = contains_substring "World" "Hello, World!" };
  590.         BooleanTest { test   = "contains_substring \"world\" \"Hello, World!\"";
  591.                       expect = false;
  592.                       result = contains_substring "world" "Hello, World!" };
  593.         IntTest { test   = "index_of_char '!' \"Hello!, World!\"";
  594.                   expect = 5;
  595.                   result = index_of_char '!' "Hello!, World!" };
  596.         IntTest { test   = "index_of \"World\" \"HelloW, World!\"";
  597.                   expect = 8;
  598.                   result = index_of "World" "HelloW, World!" };
  599.         IntTest { test   = "last_index_of_char '!' \"Hello!, World!\"";
  600.                   expect = 13;
  601.                   result = last_index_of_char '!' "Hello!, World!" };
  602.         IntTest { test   = "last_index_of \"o!\" \"Hello!, World!\"";
  603.                   expect = 4;
  604.                   result = last_index_of "o!" "Hello!, World!" };
  605.         StringTest { test   = "replace_char 'l' 'x' \"Hello, World!\"";
  606.                      expect = "Hexxo, Worxd!";
  607.                      result = replace_char 'l' 'x' "Hello, World!" };
  608.         BooleanTest { test = "null p"; expect = false; result = null p };
  609.         IntTest { test = "length p"; expect = 5; result = length p };
  610.         BooleanTest { test = "elem 3 r"; expect = true; result = elem 3 r };
  611.         StringTest { test = "head q"; expect = "foxtrot"; result = head q };
  612.         StringTest { test = "second q"; expect = "golf"; result = second q };
  613.         StringListTest { test   = "tail q";
  614.                          expect = ["golf"; "hotel"; "igloo"; "juliet"];
  615.                          result = tail q };
  616.         StringListTest { test   = "init p";
  617.                          expect = ["alpha"; "bravo"; "charlie"; "delta"];
  618.                          result = init p };
  619.         StringTest { test = "last p"; expect = "echo"; result = last p };
  620.         IntListTest { test   = "reverse r";
  621.                       expect = [10; 9; 8; 7; 6; 5; 4; 3; 2; 1];
  622.                       result = reverse r };
  623.         StringListTest { test   = "append p q";
  624.                          expect = ["alpha"; "bravo"; "charlie"; "delta"; "echo"; "foxtrot"; "golf"; "hotel"; "igloo"; "juliet"];
  625.                          result = append p q };
  626.         StringListTest { test   = "reverse_append p q";
  627.                          expect = ["echo"; "delta"; "charlie"; "bravo"; "alpha"; "foxtrot"; "golf"; "hotel"; "igloo"; "juliet"];
  628.                          result = reverse_append p q };
  629.         StringListTest { test   = "concat [p; q]";
  630.                          expect = ["alpha"; "bravo"; "charlie"; "delta"; "echo"; "foxtrot"; "golf"; "hotel"; "igloo"; "juliet"];
  631.                          result = concat [p; q] };
  632.         StringListTest { test   = "take 2 p";
  633.                          expect = ["alpha"; "bravo"];
  634.                          result = take 2 p };
  635.         StringListTest { test   = "drop 2 p";
  636.                          expect = ["charlie"; "delta"; "echo"];
  637.                          result = drop 2 p };
  638.         IntTest { test   = "foldl (fun a n -> a-n) 0 r";
  639.                   expect = -55;
  640.                   result = foldl (fun a n -> a-n) 0 r };
  641.         IntTest { test   = "foldr (fun n a -> n+a) r 0";
  642.                   expect = 55;
  643.                   result = foldr (fun n a -> n+a) r 0 };
  644.         IntTest { test   = "foldl' (fun a n -> a-n) r";
  645.                   expect = -53;
  646.                   result = foldl' (fun a n -> a-n) r };
  647.         IntTest { test   = "foldr' (fun a n -> a+n) r";
  648.                   expect = 55;
  649.                   result = foldr' (fun a n -> a+n) r };
  650.         IntListTest { test   = "map String.length p";
  651.                       expect = [5; 5; 7; 5; 4];
  652.                       result = map String.length p };
  653.         StringListTest { test   = "split_on \";\" \"aaa;bbb;;ccc\"";
  654.                          expect = ["aaa"; "bbb"; ""; "ccc"];
  655.                          result = split_on ";" "aaa;bbb;;ccc" };
  656.         StringTest { test   = "join_with \", \" [\"aaa\"; \"bbb\"; \"ccc\"]";
  657.                      expect = "aaa, bbb, ccc";
  658.                      result = join_with ", " ["aaa"; "bbb"; "ccc"] } ] in
  659.     printf "p => %s\n" (string_of_string_list p);
  660.     printf "q => %s\n" (string_of_string_list q);
  661.     printf "r => %s\n" (string_of_int_list r);
  662.     printf "t => (%s, %s)\n" (string_of_string_list p) (string_of_string_list q);
  663.     print_endline "";
  664.     List.iter print_test_result tests;
  665.     print_endline ""
Tags: ocaml
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement