Ocaml введение - PullRequest
       38

Ocaml введение

5 голосов
/ 10 мая 2010

Я пытаюсь изучить ocaml прямо сейчас и хотел начать с небольшой программы, генерирующей все битовые комбинации: [ "0", "0", "0"] [ "0", "0", "1"] [ "0", "1", "0"] ... и так далее

Моя идея заключается в следующем коде:

let rec bitstr length list =
  if length = 0 then
    list
  else begin
    bitstr (length-1)("0"::list);
    bitstr (length-1)("1"::list);
  end;;

Но я получаю следующую ошибку:

Warning S: this expression should have type unit.
val bitstr : int -> string list -> string list = <fun>
# bitstr 3 [];;
- : string list = ["1"; "1"; "1"]

Я не понял, что поменять, можешь мне помочь?

С наилучшими пожеланиями Philipp

Ответы [ 3 ]

14 голосов
/ 10 мая 2010

begin foo; bar end выполняет foo и отбрасывает результат, затем выполняет панель. Поскольку это имеет смысл только в том случае, если foo имеет побочные эффекты и не имеет значимого возвращаемого значения, ocaml выдает предупреждение, если foo имеет возвращаемое значение, отличное от unit, поскольку все остальное, скорее всего, будет ошибкой программиста (т. Е. Фактически программист для результата, который будет отброшен) - как здесь.

В этом случае действительно не имеет смысла вычислять список с "0", а затем выбрасывать его. Предположительно, вместо этого вы хотите объединить два списка. Вы можете сделать это с помощью оператора @:

let rec bitstr length list =
  if length = 0 then
    [list]
  else
    bitstr (length-1)("0"::list) @ bitstr (length-1)("1"::list);;

Обратите внимание, что я также сделал length = 0 case return [list] вместо просто list, так что в результате получается список списков вместо простого списка.

5 голосов
/ 11 мая 2010

Хотя ответ sepp2k точен, я хотел бы добавить следующую альтернативу (которая не соответствует предложенной вами подписи, но фактически делает то, что вы хотите):

let rec bitstr = function
   0 -> [[]]
 | n -> let f e = List.map (fun x -> e :: x) and l = bitstr (n-1) in 
        (f "0" l)@(f "1" l);;

Первое отличие состоит в том, что вам не нужно передавать пустой список для вызова функции bitsr 2, возвращает [["0"; "0"]; ["0"; "1"]; ["1"; "0"]; ["1"; "1"]]. Во-вторых, он возвращает список упорядоченных двоичных значений. Но что более важно, на мой взгляд, это ближе к духу ocaml.

0 голосов
/ 16 ноября 2015

Мне нравятся другие идеи!

Так вот оно ...

let rec gen_x acc e1 e2 n = match n with
| 0 -> acc
| n -> (
  let l = List.map (fun x -> e1 :: x) acc in
  let r = List.map (fun x -> e2 :: x) acc in
  gen_x (l @ r) e1 e2 (n - 1)
);;

let rec gen_string = gen_x [[]] "0" "1"
let rec gen_int    = gen_x [[]]  0   1

gen_string 2
gen_int    2

Результат:

[["0"; "0"]; ["0"; "1"]; ["1"; "0"]; ["1"; "1"]]

[[0; 0]; [0; 1]; [1; 0]; [1; 1]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...