Можно ли получить список допустимых значений в типе Erlang? - PullRequest
0 голосов
/ 07 октября 2011

Скажите, что я определяю тип:

-type yummy_foods() :: ice_cream | cake | cookies | spam.

Кажется, это отличный способ сделать то, что я сделал бы с перечислением в C. Я могу заставить Эрланга проверить меня с помощью Dialyzer. Но, скажем, я хочу составить список всех вкусных блюд и что-то с этим сделать. Как бы я получить это:

[ice_cream, cake, cookies, spam]

Меня не волнует порядок, просто все там. В качестве альтернативы, мне не хватает какой-то распространенной ирландской идиомы, из-за которой весь этот подход кажется глупым?

Ответы [ 2 ]

2 голосов
/ 08 октября 2011

Ах, мой первоначальный ответ, вероятно, не имеет значения ...

Чтобы сделать то, что вы описываете, вы должны извлечь определение типа из списка форм в файле, проанализировать его или попросить кого-то разобрать егодля вас, и если это действительно объединенный тип, извлеките элементы и верните их в список.

Если вы хотите сделать это из источника, вам понадобится что-то вроде:

get_abstract_code_from_src(Filename) ->
    get_abstract_code_from_src(Filename, init_opts()).

get_abstract_code_from_src(Filename, Opts) ->
    case compile:file(Filename, Opts) of
        {ok,_,Abs} -> {ok, Abs};
        Err -> Err
    end.

init_opts() -> [to_pp, binary, return_errors].

Если у вас нет макросов или вы хотите избежать включения заголовков, вы также можете получить формы, используя:

epp_dodger:quick_parse_file(Filename).

Оригинальный ответ:

У вас уже есть:

-type yummy_foods() :: ice_cream | cake | cookies | spam.

Вы можете использовать:

-type list_of_yummy_foods :: [yummy_foods()].

Это гарантирует, что ничего больше не будет в списке, хотя, а не все эти продукты будут.

1 голос
/ 09 октября 2011

Используйте преобразование синтаксического анализа для извлечения и преобразования форм во время компиляции, чтобы они включали новую функцию -spec yummy_foods() -> [yummy_food(),...] или даже -spec is_yummy_food(atom()) -> boolean().Преобразования синтаксического анализа трудны для написания и плохо документированы, поэтому вам нужно будет спрятаться в Интернете и прочитать, как выполняются другие преобразования синтаксического анализа.

В качестве альтернативы вы также можете следить за развитием sheriff который позволит вам проверить, является ли данный термин вкусной пищей, выполнив IsYummyFood = sheriff:check(MaybeYummyFood, yummy_food()) где -type yummy_food() :: ice_cream | cake | cookies | spam.

...