首页 > 解决方案 > Haskell(数据)构造函数构造什么?

问题描述

Haskell 使人们能够使用类型构造函数和数据构造函数来构造代数数据类型。例如,

data Circle = Circle Float Float Float

我们被告知这个数据构造函数(右边的圆)是一个在给定数据时构造一个圆的函数,例如x,y,半径。

Circle :: Float -> Float -> Float -> Circle 

我的问题是:

  1. 这个函数具体构造了什么?

  2. 我们可以定义构造函数吗?

我见过智能构造函数,但它们似乎只是最终调用常规构造函数的额外函数。

来自 OO 背景的构造函数当然具有命令式规范。在 Haskell 中,它们似乎是系统定义的。

标签: haskellfunctional-programmingalgebraic-data-types

解决方案


在 Haskell 中,不考虑底层实现,数据构造函数创建一个值,本质上是通过法令。“'让有一个Circle',程序员说,然后有一个Circle。” 询问Circle 1 2 3创造了什么类似于询问文字1在 Python 或 Java 中创造了什么。

空值构造函数更接近于您通常认为的字面量。Boolean类型在字面上定义

data Boolean = True | False

其中TrueFalse是数据构造函数,而不是 Haskell 语法定义的文字。

数据类型也是构造函数的定义;因为除了构造函数名称及其参数之外,实际上没有任何值,只需说明它就是定义。Circle您可以通过使用 3 个参数调用数据构造函数来创建类型值,Circle仅此而已。

所谓的“智能构造函数”只是一个调用数据构造函数的函数,可能还有一些其他逻辑来限制可以创建哪些实例。例如,考虑一个简单的包装器Integer

newtype PosInteger = PosInt Integer

构造函数是PosInt;智能构造函数可能看起来像

mkPosInt :: Integer -> PosInteger
mkPosInt n | n > 0 = PosInt n
           | otherwise = error "Argument must be positive"

使用mkPosInt,无法PosInteger使用非正参数创建值,因为只有正参数才会真正调用数据构造函数。当模块导出智能构造函数而不是数据构造函数时,智能构造函数最有意义,因此典型用户无法创建任意实例(因为模块外部不存在数据构造函数)。


推荐阅读