Atm*_*tye 13 haskell type-constructor
我是Haskell的新手,目前正在通过Real World Haskell.该书说,类型构造函数仅在类型签名中使用,而值构造函数在实际代码中使用.它还给出了一个声明示例,表明两者的名称彼此独立.为什么首先需要两个构造函数,如果在实际代码中只使用其中一个?由于我们不会在实际代码中使用类型构造函数,因此类型构造函数的用途是什么?
Ric*_* T. 23
也许名字有点误导.一个类型构造代表你声明类型的名称.它们之所以被称为是因为它们构建类型,而不是值:实际上,它们(可能)在类型变量上进行参数化,它们定义了一系列类型.它们的行为类似于C++的模板和Java的泛型.在data MyType a b = Constr a b,MyType是一个类型构造函数,它采用两种类型a并b构建一个新类型(MyType a b).
一个值构造是,你会调用其他(面向对象)语言"构造",因为你需要它,以建立值该类型的唯一部分.因此,在前面的示例中,如果您使用值构造函数Constr :: a -> b -> MyType a b,则可以构建一个值Constr "abc" 'd' :: MyType [Char] Char.
Mat*_*hid 16
这有点像说"为什么我们需要类和对象,如果对象是唯一实际运行的东西?"
两种构造者做不同的工作.类型构造函数进入类型签名.值构造函数使用可运行的代码.
在最简单的情况下,一种"构造" 是只是一个类型名字.在最简单的情况下,类型只有一个值构造函数.所以你最终会得到类似的东西
data Point = Point Int Int
你可能会对自己说"为什么我需要写Point两次?"
但现在考虑一个不那么简单的例子:
data Tree x = Leaf x | Branch (Tree x) (Tree x)
这Tree是一个类型构造函数.你给它一个类型参数,它"构造"一个类型.所以Tree Int是一种类型,Tree String是另一种类型,依此类推.(像C++中的模板,或Java或Eiffel中的泛型.)
另一方面,Leaf是值构造函数.给定一个值,它会生成一个1节点的树.这Leaf 5是一个Tree Int值,Leaf "banana"是一个Tree String值,等等.
同样的Branch.它需要两个树值并构造一个树节点,这些树作为子节点.例如,Branch (Leaf 2) (Leaf 7)是一个Tree Int值.
获得关于类型和值的直觉的一种方便方法是前者是编译时值,而后者是运行时值.换句话说,Type构造函数是Haskell类型集中值的构造函数,唯一的目的是在编译时键入程序.这也意味着您无法在运行时构造类型,并且无法在编译时构造值.
所以,因为你不能明确地在运行时分支类型值的基础上(尽管你可以隐式类型类),类构造器是作为执行对象,并在许多情况下,完全没有用处是在最终的二进制完全不存在.相反,因为值构造函数允许在运行时在它们的类型集中构造值,所以它们作为编译时对象完全没用.
由于这个简单的属性,Type构造函数和Value构造函数可以明确地共享名称.