2016-11-05 4 views
1

У меня есть ~ 10 функций, над которыми я хочу писать тесты, все они принимают два аргумента одного типа. Я думал, что смогу автоматизировать процесс немного, создав список всех возможных классов ввода и просто распечатав все возможные варианты с повторениями в текстовый файл. Мой код, howewer, не совсем выполняет эту работу, только перечисляя варианты, начинающиеся с «a».OCaml - найти все возможные варианты с повторениями

let x = ["a "; "b "; "c "; "d "; "e "; "f "; "g "; "h "] 
let oc = open_out file 

let rec test l1 l2 = 
    match l1 with 
    |[] -> 0 
    |h1::t1 -> 
     match l2 with 
     |[] -> test t1 l2 
     |h2::t2 -> 
      fprintf oc "%s\n" (add^h1^h2); 
      fprintf oc "%s\n" (sub^h1^h2); 
      fprintf oc "%s\n" (mul^h1^h2); 
      fprintf oc "%s\n" (div^h1^h2); 
      test l1 t2;; 
test x x; 
close_out oc; 

ответ

0

В строке |[] -> test t1 l2 вы делаете рекурсивный вызов с пустым списком для l2. Я считаю, что вместо этого вы хотите сделать звонок с начальным значением l2 (x в вашем примере), который тогда вам нужно будет хранить где-то вне фактической рекурсии. Что-то вроде

let test original_l1 original_l2 = 
    let rec loop l1 l2 = 
    ... 
     | [] -> loop l1 original_l2 
    ... 
    in 
    loop original_l1 original_l2 
0

Другой способ сделать это состоит в использовании монады (см 5 из ocaml courses):

let return x = [x];; 
let bind f l = List.fold_right (fun x acc -> (f x) @ acc) l [];; 
let (>>=) l f = bind f l;; 
x >>= fun t -> 
x >>= fun t' -> 
["add ";"mul ";"sub ";"div "] >>= fun op -> return (op^t^t') ;; 

Он возвращает список, представляющий декартово произведение х * х * Ops.

Может быть, есть лучший способ использования ocaml Аккумуляторы, которые, как представляется, реализуют все, что необходимо для декартового продукта.

 Смежные вопросы

  • Нет связанных вопросов^_^