#erlang
#erlang
Вопрос:
Я проанализировал список json, и он выходит с каждым элементом, например:
{struct,
[
{<<"name">>, "<<a name>>"},
{<<"id">>, "<<an id>>""}
]
}
Я хотел бы указать это как тип, но я получаю сообщение об ошибке со следующим, предположительно потому, что я использую два элемента в определении списка:
-type user_data() :: {struct, [{Name_key::Binary, Name_value::Binary},{ID_key::Binary, ID_value::Binary}]}.
Есть ли какой-нибудь способ сделать то, что я пытаюсь сделать?
Ответ №1:
Вы можете сделать
-type user_data() :: {struct, [{Name_key::binary(), Name_value::binary()}|{ID_key::binary(), ID_value::binary()}]}.
имеется в виду список, каждый элемент которого является либо a {Name_key::binary(), Name_value::binary()}
, либо an {ID_key::binary(), ID_value::binary()}
. Это не совсем то, что вы хотите, но может быть достаточно хорошим.
Ответ №2:
Как вы указываете, когда вы указываете типы элементов в списках, может быть указан только один тип. Дополнительные типы могут быть добавлены с использованием синтаксиса объединения, но внутренне это не сохранит информацию о порядке элементов в списке.
Так что лучше всего сделать что-то вроде:
-type user_data :: {struct, [{Key::binary(), Value::binary()}]}.
Вы также можете попробовать:
-type field() :: {Key::binary(), Value::binary()}.
-type name_field() :: field(). % Key is <<name>>
-type id_field() :: field(). % Key is <<id>>
-type fields() :: [name_field() | id_field()].
-type user_data() :: {struct, fields()}.
В этом последнем примере сохраняется вся информация, и вы можете расширить ее разумным образом.
Ответ №3:
В большинстве систем типов список like [A, B]
считается мономорфным в том смысле, что A
и B
должен иметь один и тот же тип. Это относится и к системе типа диализатора Erlangs. чтобы сделать возможным представление этого как отдельных типов, представление должно быть произведением типов, сформированных с помощью кортежа, {A, B}
который неявно также говорит, что всегда есть ровно два элемента, а именно A
и B
и они всегда встречаются вместе.
Однако существуют системы типов, которые позволяют вам иметь полиморфные списки. Одним из способов является кодирование элементов как экзистенциальных типов. Представьте, что элементы A
и B
«упакованы» таким образом, что их внутреннее представление непрозрачно для вас, и единственный способ, которым вы можете манипулировать ими, — это использовать некоторые предопределенные функции, указанные пакетом. Другой способ — использовать расширенные системы типов, обычно с зависимыми типами, где ваш тип определяется структурой списка.