和类型的结构化类型

时间:2020-05-16 06:23:11

标签: types functional-programming language-agnostic theory discriminated-union

对于产品类型,名义类型与结构类型是一种设计决策,在每种情况下都需要简单的解释;您可以使用相同的顺序和相同的字段定义两个相同的记录类型,但是名称不同;它们是兼​​容还是不兼容;很容易看到每种可能性如何导致一个连贯的类型系统。

对我来说,不清楚对总和类型是否适用;这样做的全部目的是保留标记名,以便您可以创建值并在以后区分它们。但是在名词性和结构性类型的讨论中,我找不到任何提及此问题的地方。

是这种情况吗?

  1. 当然,名义类型与结构类型仅适用于产品类型,总和类型必须是名义类型,这一点显而易见,不用多说,因此没有人会提起它。
  2. 实际上,总和类型可以是结构化的,其方式如下,我没有想到...
  3. 还有什么?

1 个答案:

答案 0 :(得分:1)

通过与您聊天,我理解您要问的是,一种新语言是否可以将等效和类型视为相同。例如,如果语法类似于ML,则可以定义

data Val  = Unparsed String | Parsed Int
data File = Filename String | FileDescriptor Int

在这里,对于ValFile,与您对产品类型所做的相同类型,可转换类型或无关类型而言,您有完全相同的选择。让我们浏览一些选项。

请注意,运行时必须跟踪求和类型的哪个组件处于活动状态,但这不必是类型名称或类型ID(除非该语言提供了直接查询活动类型的方法)。它可以静态地进行所有类型检查,将可能的格式枚举为任意整数,并使运行时与此值进行比较(例如,对匹配0x02的大小写进行二进制搜索)。将其用作功能表或其他内容的索引。

结构键入

一种可能的简单实现是对它们进行鸭子式处理。编写一种函数式语言,在其中您可以将File传递给需要Val的任何函数,并且该函数可以正常工作,这很奇怪。但这会起作用。该语言将查找定义,看到它们是等效的,并考虑它们彼此的别名。如果该语言要求选项具有相同的名称,则可能会令程序员感到惊讶。

名义打字

如果您尝试在Haskell中进行等效操作,它将告诉您这是两种不同的类型。要将一个转换为另一个,您需要编写一个可以解包和重新打包的函数,例如

fromVal (Unparsed path) = Filename path
fromVal (Parsed fd)     = FileDescriptor fd

糊状的中间

我上面编写的转换函数显然不是最佳选择,因为这两种类型的布局和实现完全相同。您无需做任何实际的工作即可将一个转换为另一个。

在这里,该语言可能具有中间立场:您必须在类型之间进行显式转换,但这种转换是无操作的。进一步走入歧义的一步可能是要求在某处声明以启用这种微不足道的转换,有点像C ++中的default构造函数或Haskell中的deriving。编译器将能够自动编写它。

这在命令式语言中很常见。例如,在C语言中,如果两种类型是“布局兼容的”,或者即使它们是前几个字段都是布局兼容的产品类型,也可以保证它们之间的类型修改。

无处不在的套接字库依靠它来实现struct sockaddr,实际上是求和类型。但是,副作用是,如果实现的新网络协议具有32位字段和16位字段,则该语言将认为与IPv4地址以及TCP或UDP端口号兼容。由于类型兼容性是结构性的,因此无法禁用它(甚至无法使语言停止您的脚步,因为类型双关语的方法是覆盖所有类型检查)。但是内核级编程通常需要这种类型的对等处理。

相关问题