2011-10-05 17 views
2

我已經解析了一個JSON列表,並談到了與像每一個元素:超過一個定義的元素列表規範

{struct, 
[ 
    {<<"name">>, "<<a name>>"}, 
    {<<"id">>, "<<an id>>""} 
] 
} 

我想說明這是一個類型,但我得到一個錯誤可能是因爲我在列表定義中使用了兩個元素:

-type user_data() :: {struct, [{Name_key::Binary, Name_value::Binary},{ID_key::Binary, ID_value::Binary}]}. 

有沒有什麼辦法可以做我想做的事情?

回答

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

正如您指出的那樣,當您指定列表中元素的類型時,只能提供一種類型。可以使用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()}. 

後一個例子保留了所有的信息,您可以以合理的方式進行擴展。

0

在大多數類型的系統中,像[A, B]這樣的列表被認爲是單形的,因爲AB必須具有相同的類型。 Erlangs透析器類型系統也是如此。爲了能夠將其表示爲不同的類型,該表示需要是由元組形成的類型的產物,這暗示還總是存在兩個元素,即AB,並且它們總是一起出現。

但是有類型的系統可以讓你擁有多態列表。一種方法是將元素編碼爲存在類型。想象一下,元素AB是「封裝」的,使得它們的內部表示對你來說是不透明的,並且唯一可以操縱它們的方法是通過包中指定的一些預定功能。另一種方法是使用高級類型系統,通常使用依賴類型,其類型由列表的結構決定。

相關問題