我正在阅读《Haskell表达之学校》这本书,第5章开头的第56页,我看到了“多态数据类型”和“多态类型”这两个术语。
这两个术语是指同一个概念吗?
它们是同义词吗?
还是两者之间有区别?如果有,是什么?
这两个术语是指同一个概念吗?
它们是同义词吗?
还是两者之间有区别?如果有,是什么?
::
的右侧,将左侧的表达式分类。每个类型语法组件本身都有一个种类,其中用于分类表达式的类型种类为 *
。然而,一些人乐意使用“类型”这个词来指代类型语法中的任何组件,无论它们的种类是否允许对表达式进行分类。type Foo x y z = [x] -> IO (y, z)
,添加了完全应用形式 Foo
x y z 的类型组件,并根据其定义方程式进行宏扩展。data Goo x y z = ThisGoo x | ThatGoo (Goo y z x)
,引入了新的类型构造器符号 Goo
到类型的语法中,该符号用于构建由数据构造器(data constructors)生成的值所分类的类型,这里的数据构造器是 ThisGoo
和 ThatGoo
。newtype Noo x y z = MkNoo (x, [y], z)
,创建了一个现有类型的副本,并在类型的语法中与原始类型区分开来。Maybe
是一个多态数据类型",当他们真正意思是类型构造器有参数(因此可以用来形成多态类型),严格地说,你确实声明了一个多态数据类型,但并不是任何旧的多态数据类型,而是一个类型构造器应用于形式参数)。非正式用法通常介于两者之间,定义并不十分清晰。人们经常在某种功能或过程与它们操作的“数据”之间进行某种区分。或者他们可能认为数据是“基于它们的制作方式理解的”(通过模式匹配暴露它们的表示),而不是“基于它们的使用方式理解的”。这种“数据”的最后一种用法与抽象数据类型的概念有些不协调,抽象数据类型是一种隐藏底层内容表示的类型。因此,隐藏表示的抽象数据类型与暴露表示的代数数据类型形成了相当强烈的对比,这就是为什么“ADT”被随意用作两者的缩写的原因,这非常不幸。
总之,我很遗憾地说,这种用法存在一定的含糊性。
Set a
是抽象数据类型的一个示例:您可以获得接口(带有空集、联合、交集、各种测试等),但无法访问实际表示(实际上可能只使用列表,但据我所知,它实际上是一些巧妙的二叉树结构)。 - pigworkerdata Status = Ready | NotReady | Exploded
在Haskell中,Ready
、NotReady
和Exploded
是新的构造函数。
另一方面,有一个type
关键字,它仅仅创建了一个对现有类型的别名:
type Status = String
ready, notReady, exploded :: Status
ready = "Ready"
notReady = "NotReady"
exploded = "Exploded"
type FilePath = String
doSomething :: FilePath -> IO ()
那么你立即知道要传递一个文件名,与之相比
doSomething :: String -> IO ()
你对这个函数的作用一无所知,除了“做某些事情”之外。它们通常也用于减少输入,例如:
type Point = (Double, Double)
Point
而不是(Double, Double)
,这样更短更易读。
data
声明了一个全新的类型,完全根据您的需求定制,而type
应该被重命名为alias
,以便于初学Haskell的人们避免混淆。type
是 data/type/newtype
中唯一有意义的。其他两个由于使用 =
的荒谬用法和类型级别和项级别标识符的混合而语法上令人困惑。type
是一个直接的类型级自然函数(自然变换)。 - jberrymantype
和data type
指的是同一个概念,polymorphic type
和polymorphic data type
也是如此。
为了说明两个短语可以一起使用(没有任何意义上的区别),考虑以下表达式。
data Maybe a = Just a | Nothing
我可以说,我刚刚定义了一个多态数据类型Maybe
,它具有多态类型参数a
。
data
视为struct
和union
的组合,而type
则类似于typedef
。然而,Haskell 数据类型比其 C 语言对应物更加强大(data
允许使用更多构造,因为有所有可用的扩展)。 - didierc