我正在阅读polymorphic types,唯一的例子是元组:
type queue(Type) :: {fifo, list(Type), list(Type)}.
我有这样的记录:
-record(heap_node, { item :: any(), children :: [#heap_node{}] }).
-type heap_node() :: #heap_node{}.
现在我无法将类型参数传递给记录。在Erlang中有可能吗?
答案 0 :(得分:4)
您可以在item
中创建一个多态的类型:
-type heap_node(A) :: #heap_node{item :: A}.
但A
不会延续到children
字段 - 这些heap_node
记录仍然会有一个不受限制的item
字段。
我尝试递归使用该类型:
-type heap_node(A) :: #heap_node{item :: A, children :: [heap_node(A)]}.
但是Dialyzer并不喜欢这样:
dialyzer: Analysis failed with error:
foo.erl:9: Illegal declaration of #heap_node{children}
答案 1 :(得分:4)
-type queue(Type) :: {fifo, list(Type), list(Type)}.
您可能希望将其表示为:
-type queue(term()) :: {fifo, [term()], [term()]}.
这并不意味着这些是一致的条款。 term()
是any()
的别名,只是意味着"您有一系列事物",而不是"同质事物列表"。
这里更重要的问题是问你要做什么?你想要达到的整体效果是什么? Erlang标准库具有大量数据结构,可以非常有效地处理队列,包,集合,集合,地图,树等等。
当然,您有特定需求的情况是您自己编写的。每当您有特定需求时,您会发现自己需要开放式类型(如term()
)或严格类型(如non_neg_integer()
或#{integer() := pid()}
)。
如果我们对您尝试实现的整体效果有了更多了解,那么可能会避免花费大量精力重新发明OTP或stdlib。
关于Erlang的哲学
请记住, Erlang不是一种学术语言。它是一种实用的工业语言,它受到学术概念的影响,因为它们是有效语言和系统设计的自然结果 - 在它创建的时代。
是:
(顺便提一下,您可能会想到的大多数其他热门流行语也恰好描述了Erlang,但这只是偶然的.Erlang恰好完全符合流行语,可能会持续几十年。)
这意味着Dialyzer是一个允许的 typer,而不是 strict typer - 它假设类型正确,直到它可以证明不是这样。严格的打字机是另一个方向,假设类型错误,除非它可以证明或推断否则。所以没有多态类型,因为程序中的所有内容都被假定为多态,直到类型约束可以通过分析或通过类型语言显式推断出来。例如,你在Erlang类型系统中找不到与Haskell一样多的能力 - 但你会发现整个系统专门用于实现真实世界的程序,尽管你的思维方式可能在开发中有点不同。
另请参阅:dialyzer not detecting guard violation when function is exported