我正在读这本书: Haskell表达式学校和第56页,在第5章的开头,我读了“多态数据类型”和“多态类型”这两个术语。
这两个术语是指同一个概念吗?
它们是同义词吗?
还是两者之间有什么区别?如果是什么?
发布于 2014-07-18 16:33:47
类型(在Haskell中)是一种语法,它可以有意义地放在::的右边来对::的左侧表达式进行分类。类型的每个语法组件本身都由一个类分类,其中类型(对表达式进行分类)的类型是*。有些人很乐意使用" type“这个词来指类型语法的任何组件,不管它的类型是否允许对表达式进行分类。
类型的语法可以通过各种声明表单进行扩展。
type Foo x y z = [x] -> IO (y, z),添加了完全应用的Foo x y形式的类型组件,这些组件根据它们的定义方程扩展了宏方式。data Goo x y z = ThisGoo x | ThatGoo (Goo y z x)在类型语法中引入了一个新的类型构造函数符号Goo,用于构建对数据构造函数生成的值进行分类的类型,此处ThisGoo和ThatGoo。newtype Noo x y z = MkNoo (x, [y], z)生成一个现有类型的副本,该副本在类型的语法上与原始类型不同。一个类型是多态,如果它包含类型变量,可以用其他类型组件替换它:按多态类型分类的值可以是专用的,用于类型变量的任何替换实例。例如,追加(++) :: [a] -> [a] -> [a]在元素具有相同类型的列表上工作,但任何类型都可以。具有多态类型的值通常称为“多态值”。
有时,“数据类型”很简单地用来表示由data声明引入的类型。从这个意义上说,所有数据类型都是类型,但并非所有类型都是数据类型。非数据类型的示例包括IO ()和Int -> Int。而且,从这个意义上说,Int不是一种数据类型:它是一种硬连接的原始类型。为了避免疑问,有些人称这些类型为代数数据类型,因为构造函数给出了一个代数,意思是“通过合并其他值来构造值的一系列操作”。“多态数据类型”是一种数据类型,其中包含类型变量,例如[(a, Bool)],与[Int]形成对比。有时人们谈论“声明一个多态数据类型”或者说"Maybe是一个多态数据类型“,而他们实际上只是指类型构造函数有参数(因此可以用来形成多态类型):实际上,一个人确实声明了一个多态数据类型,但不是任何旧的多态数据类型,而是一个应用于形式参数的类型构造函数)。
当然,按类型分类的所有一级值在某种意义上都是“数据”,而在Haskell中,类型不用于对任何不是头等值的事物进行分类,因此在这种松散的意义上,每一种“类型”都是“数据类型”。在具有类型(例如,Java中的方法)的数据以外的事物中,这种区别在语言中变得更有意义。
非正式用法通常在中间的某个地方,而不是很清楚的定义。人们常常在某种程度上区分函数或进程和他们所操作的东西(“数据”)。或者,他们可能认为数据是“从他们的制作方式来理解的”(并且公开他们的表示,例如通过模式匹配),而不是“用他们的使用方式来理解”。“数据”的最后一种用法与抽象数据类型的概念有些不协调,因为它是一种隐藏底层内容表示的类型。因此,表示--隐藏抽象数据类型与表示法形成了强烈的对比--暴露了代数数据类型,这就是为什么"ADT“被随意用作这两种类型的缩写的原因。
恐怕结果是模糊的。
发布于 2014-07-18 14:07:36
在这种情况下,data type和type是同义词。但是,我承认可能会出现混淆,因为Haskell有两个关键字data和type,它们执行两个非常不同的功能。为了保持清晰的区别,重要的是要注意上下文。每当您谈论签名中的类型或一般类型时,术语“数据类型”和“类型”几乎总是指相同的东西。每当您谈到在代码中声明类型时,可能会有不同之处。
使用data声明的类型是一个新的、用户定义的类型,因此您可以执行以下操作
data Status = Ready | NotReady | Exploded其中Ready、NotReady和Exploded是没有包含在Haskell中的新构造函数。
另一方面,有type关键字简单地为现有类型创建别名:
type Status = String
ready, notReady, exploded :: Status
ready = "Ready"
notReady = "NotReady"
exploded = "Exploded"在这里,Status只是String的别名,在任何使用String的地方都可以使用Status,反之亦然。没有任何构造函数,只需要使用预构建的值。这种方法不太安全,如果您使用这样的方法,您将在某个时候遇到错误。type声明通常用于使某些参数更清楚地说明它们的用途,例如
type FilePath = String这是GHC中内置的别名,如果您看到一个函数
doSomething :: FilePath -> IO ()然后,您就知道立即将文件名传递给它,与
doSomething :: String -> IO ()除了“某样东西”,你不知道这个函数是做什么的。它们也通常用于减少打字,例如:
type Point = (Double, Double)现在,您可以在您的类型签名中使用Point而不是(Double, Double),这样编写的时间更短,可读性更强。
总之,data为您声明了一种全新的类型,完全是自定义的,type应该被重命名为alias,这样人们在第一次接近Haskell时就不会对它们感到困惑。
发布于 2014-07-18 14:07:30
type和data type指的是相同的概念,polymorphic type和polymorphic data type也是如此。
为了说明这两种短语都可以完全使用的情况(在意义上没有任何区别),请考虑这个短语。
data Maybe a = Just a | Nothing我可以说,我刚刚定义了一个多态数据类型Maybe,其中包含多态类型参数a。
https://stackoverflow.com/questions/24826657
复制相似问题