Types 求和类型的结构类型

Types 求和类型的结构类型,types,functional-programming,language-agnostic,theory,discriminated-union,Types,Functional Programming,Language Agnostic,Theory,Discriminated Union,对于产品类型,名义类型与结构类型是一个设计决策,在每种情况下都有一个简单的解释;您可以定义两种相同的记录类型,它们的字段顺序相同,但名称不同;要么兼容,要么不兼容;很容易看出每种可能性是如何导致一个连贯的类型系统的 我不清楚这是否也适用于总和类型;它们的全部要点是保留标记名,以便创建值并在以后区分它们。但是,在讨论名词性和结构性类型时,我没有发现有人提到这个问题 是否有以下情况: 当然,名义类型和结构类型只适用于产品类型,总和类型必须是名义类型,这一点很明显,不用说,所以没有人愿意提及它 实际上

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

我不清楚这是否也适用于总和类型;它们的全部要点是保留标记名,以便创建值并在以后区分它们。但是,在讨论名词性和结构性类型时,我没有发现有人提到这个问题

是否有以下情况:

  • 当然,名义类型和结构类型只适用于产品类型,总和类型必须是名义类型,这一点很明显,不用说,所以没有人愿意提及它
  • 实际上,和类型可以是结构化的,按照我没有想到的方式
  • 还有别的吗

  • 从与您的交谈中,我理解您要问的是,一种新语言是否可以将等价和类型视为相同类型。例如,如果语法类似于ML,则可以定义

    data Val  = Unparsed String | Parsed Int
    data File = Filename String | FileDescriptor Int
    
    关于
    Val
    File
    是否被视为与产品类型相同的类型、可转换类型或不相关类型,您在这里有完全相同的选择。让我们看一下一些选项

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

    结构分型 一个可能的简单实现是duck类型。如果编写一种函数式语言,您可以将
    文件
    传递给任何接受
    Val
    的函数,那么它就可以正常工作,这会很奇怪。但这只会起作用。语言会查找定义,看它们是等价的,并把它们看作别名。如果语言要求选项具有相同的名称,那么程序员可能不会感到惊讶

    名义打字 如果你尝试在Haskell中做同样的事情,它会告诉你这是两种不同的类型。要将一个转换为另一个,您需要编写一个解包和重新打包的函数,例如

    fromVal (Unparsed path) = Filename path
    fromVal (Parsed fd)     = FileDescriptor fd
    
    糊状的中间 我上面写的转换函数显然是次优的,因为这两种类型具有完全相同的布局和实现。您不需要做任何实际的工作来将一个转换为另一个

    语言可能在中间有一个中间点:必须在类型之间进行显式转换,但转换是NO-OP。甚至在进一步矛盾的过程中,可能需要在某个地方进行声明以实现这种琐碎的转换,有点像C++中的<代码>默认< /COD>构造器,或者在Haskell中派生< <代码> >。编译器将能够自动编写它

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


    无处不在的套接字库依赖于此将
    struct sockaddr
    实现为实际上的总和类型。作为副作用,如果您实现了一个具有32位字段和16位字段的新网络协议,则该语言将考虑与IPv4地址和TCP或UDP端口号兼容。由于类型兼容性是结构性的,因此无法禁用此功能(甚至无法让语言阻止您攻击自己,因为使用类型双关语的方法是覆盖所有类型检查)。但是内核级编程通常需要这种类型双关。

    Typescript追求结构化类型。当您忽略名称时,标记就会变为。我认为这种方法相当不可靠,但他们就是这样做的。@bob-Hmm!我不知道typescript,但如果我正确理解了代码片段,它似乎在将名称转换为字符串字段?因此,实现了命名类型化——名称作为一个区别因素而存在——而没有一个这样的命名类型系统。他们称之为有区别的联合(标记联合的同义词),其中一个特殊属性扮演鉴别的角色,其值表示标记。正如您所看到的,判别式的每个值都对应于类型构造函数的名称。这是一个相当令人困惑的部分,因为通常值构造函数的名称提供标记,这些标记在编译过程中不会被删除。因此,根据Davidslor的回答,两个数据声明
    Val
    /
    文件
    在TS中被视为相等。这感觉是错误的,因为结构类型忽略了数据类型的语义中没有反映在其结构中的部分。