Таким образом, я использовал Erlang в течение прошлых восьми часов, и я потратил два из тех, которые ударяют моей головой о клавиатуру, пытающуюся выяснять ошибку исключения, которую моя консоль продолжает возвращать.
Я пишу программу игры в кости для изучения erlang. Я хочу, чтобы это смогло звонить с консоли на erlang интерпретатор. Программа принимает много игр в кости и, как предполагается, генерирует список значений. Каждое значение, как предполагается, между один и шесть.
Я не буду переносить Вас с десятками отдельных микроизменений, которые я сделал, чтобы попытаться решить проблему (случайная разработка), но я отправлю свой код и ошибку.
Источник:
-module(dice2).
-export([d6/1]).
d6(1) ->
random:uniform(6);
d6(Numdice) ->
Result = [],
d6(Numdice, [Result]).
d6(0, [Finalresult]) ->
{ok, [Finalresult]};
d6(Numdice, [Result]) ->
d6(Numdice - 1, [random:uniform(6) | Result]).
Когда я запускаю программу от своей консоли как так... dice2:d6(1).
... Я получаю случайное число между один и шесть как ожидаемый. Однако, когда я выполняю ту же функцию с любым числом выше, чем одно как аргумент, я получаю следующее исключение...
** ошибка исключения: никакой функциональный пункт, соответствующий dice2:d6 (1, [4|3])
... Я знаю меня, у меня нет функции с соответствием аргументам, но я не знаю, как записать функцию с аргументами переменной и переменное количество аргументов.
Я пытался изменить рассматриваемую функцию как так....
d6(Numdice, [Result]) ->
Newresult = [random:uniform(6) | Result],
d6(Numdice - 1, Newresult).
... но я получил по существу ту же ошибку. Кто-либо знает то, что продолжается здесь?
По сути, это ошибка типа. Когда Result
является списком, [Result]
является списком с одним элементом. Например, если бы ваша функция работала, она бы всегда возвращала список с одним элементом: Finalresult
.
Вот что происходит (используя ==>
для "сводится к"):
d6(2) ==> %% Result == []
d6(2, [[]]) ==> %% Result == [], let's say random:uniform(6) gives us 3
d6(1, [3]) ==> %% Result == 3, let's say random:uniform(6) gives us 4
d6(0, [4|3]) ==> %% fails, since [Result] can only match one-element lists
Предположительно, вы не хотите, чтобы [[]]
в первом вызове, и вы не хотите, чтобы Result
был равен 3 в третьем вызове. Так что это должно исправить ситуацию:
d6(Numdice) -> Result = [], d6(Numdice, Result). %% or just d6(Numdice, []).
d6(0, Finalresult) -> {ok, Finalresult};
d6(Numdice, Result) -> d6(Numdice - 1, [random:uniform(6) | Result]).
Урок: если язык динамически типизирован, это не значит, что вы можете избежать правильного определения типов. Наоборот, это означает, что компилятор не поможет вам в этом в той мере, в какой мог бы.