Ошибка исключения в Erlang

Таким образом, я использовал 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).

... но я получил по существу ту же ошибку. Кто-либо знает то, что продолжается здесь?

6
задан Caramiriel 1 May 2015 в 06:31
поделиться

1 ответ

По сути, это ошибка типа. Когда 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]).

Урок: если язык динамически типизирован, это не значит, что вы можете избежать правильного определения типов. Наоборот, это означает, что компилятор не поможет вам в этом в той мере, в какой мог бы.

6
ответ дан 17 December 2019 в 02:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: