在Erlang中是否可以使用多态记录?

在Erlang中是否可以使用多态记录?,erlang,Erlang,我在读关于,唯一的例子是一个元组: type queue(Type) :: {fifo, list(Type), list(Type)}. 我有这样的记录: -record(heap_node, { item :: any(), children :: [#heap_node{}] }). -type heap_node() :: #heap_node{}. 现在我无法将类型参数传递给记录。在Erlang中可能吗?您可以在项中创建多态类型: -type heap_node(A) :: #he

我在读关于,唯一的例子是一个元组:

type queue(Type) :: {fifo, list(Type), list(Type)}.
我有这样的记录:

-record(heap_node, { item :: any(), children :: [#heap_node{}] }).
-type heap_node() :: #heap_node{}.

现在我无法将类型参数传递给记录。在Erlang中可能吗?

您可以在
项中创建多态类型:

-type heap_node(A) :: #heap_node{item :: A}.
但是
A
不会结转到
子项
字段-那些
heap\u节点
记录仍会有一个不受限制的
字段

我尝试递归地使用该类型:

-type heap_node(A) :: #heap_node{item :: A, children :: [heap_node(A)]}.
但透析器不喜欢这样:

dialyzer: Analysis failed with error:
foo.erl:9: Illegal declaration of #heap_node{children}
您可能希望将其表示为:

-type queue(term()) :: {fifo, [term()], [term()]}.
这并不意味着这些术语是一致的
term()
any()
的别名,意思是“你有一个事物列表”,而不是“同质事物列表”

这里更重要的问题是问你想做什么?你想要达到的总体效果是什么?Erlang标准库有大量的数据结构,可以非常有效地处理队列、包、集合、集合、地图、树等

当然,你有特定需求的情况是你自己写的。每次您有特定需求时,您都会发现自己需要广泛开放的类型(如
term()
)或严格类型(如
非负整数()
{integer():=pid()}

如果我们对您试图实现的总体效果了解多一点,那么就有可能避免花费大量精力重新发明OTP或stdlib

关于二郎的哲学

请记住,Erlang不是一种学术语言。它是一种实用的工业语言,受学术概念的影响,因为它们是有效语言和系统设计的自然产物——在它创建的时代

它是:

  • 功能性——但这仅仅是因为这是在编写大量并发且无法用共享状态OOP推理的真实世界程序时保持头脑清醒的最有效方法
  • 坚持“参与者模型”——但早于该术语,因此不能说是“它的实现”。它看起来像一个参与者模型,因为这也是唯一一种对大规模并发系统建模并表示进程之间清晰划分的明智方法
  • 反应性——但也早于该术语(作为一个时髦词应用于软件)。这是使用消息传递模型的附带结果
  • 有一个类型系统——但它后来发展成为一种功能性语言的积极副作用。但它不是一种“纯”函数式语言,因为用它编写的大多数程序都会产生副作用,而类型系统必须很弱,因为运行时处理动态调用和生成等的方式
(顺便说一句,您可能想到的大多数其他热门词汇也恰巧描述了Erlang,但这又是偶然的。Erlang恰好完全符合流行语,而且可能还会持续几十年。)

这意味着透析器是一个允许的打字机,而不是一个严格的打字机——它假设类型正确,直到它可以证明其他。严格的打字机则相反,除非它能证明或推断出其他情况,否则它会假定类型错误。因此没有多态类型,因为程序中的所有内容都被假定为多态的,直到类型约束可以通过分析推断或通过类型语言显式化。例如,您在Erlang类型的系统中找不到Haskell那样强大的功能,但您会发现整个系统专门用于将真实世界的程序推出,尽管您在开发中的心态可能有点不同

另见:

-type queue(term()) :: {fifo, [term()], [term()]}.