Haskell ADT理论或在编程语言中如何处理它确实有问题?
我不是数学家,但我觉得有一些逻辑问题 让我们从ADT原语开始,例如“unit”类型。它应该在类型集的上下文中扮演“1”的角色。但实际上,我们看到了“单位”类型,通常称为“空”,在C,C++等。同时,我们有自己的“空”类型在ADT中,扮演“0”的角色,并且实际上不定义自己的值。p> 关于这一点的一些观点听起来像“单位类型不会带来任何信息,因此它是无用的,我们可以把它看作是一种虚无”。但是,C void的等价物在哪里呢?或者,void=单位,“0=1”?带来一些悖论是个坏主意 那么,让我们深入一点。单位类型只定义一个值,好的。但是,为什么在ADT理论中Haskell ADT理论或在编程语言中如何处理它确实有问题?,haskell,algebraic-data-types,type-theory,unit-type,Haskell,Algebraic Data Types,Type Theory,Unit Type,我不是数学家,但我觉得有一些逻辑问题 让我们从ADT原语开始,例如“unit”类型。它应该在类型集的上下文中扮演“1”的角色。但实际上,我们看到了“单位”类型,通常称为“空”,在C,C++等。同时,我们有自己的“空”类型在ADT中,扮演“0”的角色,并且实际上不定义自己的值。p> 关于这一点的一些观点听起来像“单位类型不会带来任何信息,因此它是无用的,我们可以把它看作是一种虚无”。但是,C void的等价物在哪里呢?或者,void=单位,“0=1”?带来一些悖论是个坏主意 那么,让我们深入一点。
unit + unit = 2*unit
我们什么时候能拿到单位?“+”的工作原理类似于“或”定义类型,我们称之为变体类型。
“单位”或“单位”绝对不会给我们“比特”,或任何更复杂的东西
提到haskell元组,它甚至没有单个元素的元组,但可以是空的。
所以它也是来自ADT理论。Tuple是项类型的乘法,因此一个元素Tuple与裸元素相同,空Tuple是单位值()
所以,这里有一个悖论:空元组的长度是多少?正如你所看到的,它的长度是零,同时是一…首先,我们需要忽略C类语言等:它们甚至不试图匹配数学基础 Haskell和其他函数式语言确实尝试了这一点,虽然同构的工作原理通常并不明显,但它们确实存在 那么,让我们深入一点。单位类型只定义一个值,好的。但是,为什么在ADT理论中
unit + unit = 2*unit
我们什么时候能拿到单位?“+”的工作原理类似于“或”定义类型,我们称之为变体类型。“单位”或“单位”绝对不会给我们“比特”,或任何更复杂的东西
嗯,是的,它确实给了我们一些信息
type Bit = Either () ()
(||), (&&) :: Bit -> Bit -> Bit
(Left()) || (Left()) = Left()
_ || _ = Right()
(Right()) && (Right()) = Right()
_ && _ = Left()
如果您认为它不起作用:
前奏曲顶点导弹>类型位=任一()()前奏曲Acme.飞弹>让[真,假]=[左(),右()]::[位]
前奏曲Acme.飞弹>如果为真==假,则启动飞弹否则返回()
正在加载程序包stm-2.4.2。。。链接。。。完成。
加载包acme-飞弹-0.3。。。链接。。。完成。
前奏曲极致导弹> 啊,谢天谢地,我们还活着
至于“嵌套的单元元组”:它们只是表示
1的事实ⁿ ≡ 1
当我们真正考虑零类型时,事情可能变得更清楚了。
{-# LANGUAGE EmptyDataDecls #-}
data Void
现在,让我们看一下最简单的情况:
- 0*0=0。因为我们不能为元组的任何一侧提供值,所以我们不能定义
(Void,Void)类型的值≅ 作废
- 0+0=0。虽然
提供了两个构造函数,但这两个构造函数都需要一个other
参数,我们无法提供该参数,因此仍然有Void
other-Void≅ 作废
- 0*1=0。我们无法构造
,因为我们无法为(Void,())
提供值fst
- 0+1=1。啊哈!我们不能构造
左侧的
,但我们可以构造
!所以右侧的()
,因为这是此类型的单个值Void()≅ ()
- 1*1=1。元组的两侧只能接受值
()
- 1+1=2。这就是我在上面讨论的情况,它有不同的值
和Left()
Right()
- 2+3=…darn,顺便说一句,⟂ 就在外面
+
和Haskell中的或都不一样:它跟踪使用哪个字段,不管两者是否具有相同的类型。-“元组的长度”没有定义,所以没有理由谈论它。@user3002392不,它们不一样。它们包含相同数量的信息,但可以区分。这就像说真与假是一样的,因为它们传递的信息量相同。@user3002392:(a,b,c,d)
同构于((a,b),(c,d))
,所以你同样可以说它的长度是两个。那些元组与任何“相似列表”都不同构当然,Haskell将这些类型视为不同的类型是对的,但这发生在类型系统级别。类型系统仅仅为我们提供了一个框架,在这个框架中我们可以拥有ADT对象的代表。哦,对于(a,b,c,d)
和((a,b),(c,d))
“它是不同的值”这句话是没有意义的:这些类型的值既不能相等也不能不同,因为类型系统不允许我们=
它们。但存在(忽略)⟂) 一个唯一的同构sp::(a,b,c,d)->((a,b),(c,d))
,WRT它们是相同的。@如果您没有考虑“它们的包装器”(与其他任何东西一样是值的一部分),请使用3002392您将不再拥有ADT。ADT的优势在于能够组合类型并区分不同的组合。想象一下,如果您无法区分第3行第5列“
上的Left”意外符号和x==5时的Right”之间的差异,那么或将是多么无用:
--我们将再次回到只使用字符串的状态!cf。
{-# LANGUAGE EmptyDataDecls #-}
data Void