я пытаюсь изучить 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
begin foo; bar end
выполняет foo
и отбрасывает результат, затем выполняет bar. Поскольку это имеет смысл только в том случае, если foo
имеет побочные эффекты и нет значимого возвращаемого значения, ocaml выдает предупреждение, если foo имеет возвращаемое значение, отличное от единицы, поскольку все остальное, скорее всего, будет ошибкой программиста (т. Е. Программист на самом деле не предполагает, что результат будет отброшен) - как здесь.
В этом случае действительно нет смысла вычислять список с «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
, поэтому результатом будет список списков вместо простого списка.
Хотя ответ 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.