我已经解析了一个json列表,它出现在每个元素中:
{struct,
[
{<<"name">>, "<<a name>>"},
{<<"id">>, "<<an id>>""}
]
}
我想将此指定为一种类型,但我得到以下错误,可能是因为我在列表定义中使用了两个元素:
-type user_data() :: {struct, [{Name_key::Binary, Name_value::Binary},{ID_key::Binary, ID_value::Binary}]}.
有什么办法可以做我想做的事吗?
答案 0 :(得分:2)
你可以做到
-type user_data() :: {struct, [{Name_key::binary(), Name_value::binary()}|{ID_key::binary(), ID_value::binary()}]}.
表示每个元素都是{Name_key::binary(), Name_value::binary()}
或{ID_key::binary(), ID_value::binary()}
的列表。这不是你想要的,但也可能足够好。
答案 1 :(得分:1)
正如您所指出的,当您在列表中指定元素类型时,只能提供一种类型。可以使用union语法添加其他类型,但在内部不会保留有关列表中元素顺序的信息。
所以你最好的选择是:
-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()}.
后一个例子保留了所有信息,你可以以合理的方式扩展它。
答案 2 :(得分:0)
在大多数类型系统中,[A, B]
之类的列表在A
和B
必须具有相同类型的意义上被视为单态。这也是Erlangs透析器类型系统的情况。为了能够将它表示为不同的类型,表示需要是类型的乘积,由元组{A, B}
形成,它隐含地也表示总是有两个元素,即A
和B
他们总是一起出现。
有些类型系统允许您拥有多态列表。一种方法是将元素编码为存在类型。想象一下,元素A
和B
被“打包”,使得它们的内部表示对你来说是不透明的,你可以操纵它们的唯一方法是通过包指定的一些预定函数。另一种方法是使用高级类型系统,通常使用依赖类型,其类型由列表结构决定。