具有多个已定义元素的列表规范

时间:2011-10-05 01:19:03

标签: 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}]}.

有什么办法可以做我想做的事吗?

3 个答案:

答案 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]之类的列表在AB必须具有相同类型的意义上被视为单态。这也是Erlangs透析器类型系统的情况。为了能够将它表示为不同的类型,表示需要是类型的乘积,由元组{A, B}形成,它隐含地也表示总是有两个元素,即AB他们总是一起出现。

有些类型系统允许您拥有多态列表。一种方法是将元素编码为存在类型。想象一下,元素AB被“打包”,使得它们的内部表示对你来说是不透明的,你可以操纵它们的唯一方法是通过包指定的一些预定函数。另一种方法是使用高级类型系统,通常使用依赖类型,其类型由列表结构决定。