我试图了解如何使用以下内容:
data Maybe a = Nothing | Just a
data Either a b = Left a | Right b
根据我的理解,这些是参数化代数数据类型。来自OO背景,我现在想创建这些对象的实例。如果我这样做:
x = Maybe 10
现在它是子类/子代数数据类型,还是想知道该对象被调用了什么。我认为它是某种类型。如果是这样,那么我想知道如何创建x
的实例。在OO土地上我会这样做:
myinstance = new x
这是来到Haskell让我迷路的地方,我不知道在哪里搜索。总结一些问题:
x
。如果Maybe
是参数化数据类型,那么x是〜something~ 类型,不确定。x
。x
实例是什么,因为我们通过它10.想知道,如果实例值是10并且类型为Int。答案 0 :(得分:5)
Haskell中没有Maybe 10
这样的东西。有Maybe Int
,这是类型。
我们创建某种类型的值,直接,如
x :: Maybe Int
x = Just 10
或
y :: Maybe Int
y = Nothing
简单直接。
编辑: Maybe
是类型构造函数。 Just
和Nothing
是数据构建器。通过编写Maybe Int
我们“创建”一种类型。没有定义z :: Maybe ; z = .....
。
这被称为“善意”:Maybe
的类型为* -> *
,例如Int
是*
,Maybe Int
也是:k
。在GHCi提示符下尝试~> :k Int
Int :: *
~> :k Maybe
Maybe :: * -> *
~> :k Maybe Int
Maybe Int :: *
以查看:
"Maybe Int
当然我们写Maybe
时实际上并没有创建新类型,只是*
本身并不是一种东西(“东西”类型有种类{{ 1}})。
Maybe
的定义是为我们可能使用的任何Maybe a
创建类型a
的内容。这称为参数多态。
所以在Haskell中,我们没有对象(在OOP意义上)。我们有价值观和类型。
答案 1 :(得分:2)
上面是什么样的物体x。如果Maybe是参数化数据类型,则x是〜某种〜类型,不确定。
您无法构建Maybe 10
,例如,您可以构建Just 10
。如果10
在这里Int
(从技术上讲,它可以是任何数字类型,但我们暂时忽略它),那么您构建了Maybe Int
请注意a
中的Maybe a
是一个 meta 级别:它适用于类型。因此a
是类型参数。因此,它不会取值10
,而是例如Int
。
可以为Maybe Int
定义类型别名,例如:
type X = Maybe Int
请注意,我们在此处使用type
作为类型别名 not data
来构建数据类型。
类型(和类型别名)始终以大写字母开头,因此我们无法定义类型x
,只能定义类型X
。类型具有 no 默认构造函数(在OO编程语言中通常就是这种情况)。
如何创建x的实例。
Haskell可以派生出一个表达式最通用的类型。因此,我们编写了一个类型为Maybe Int
的表达式,例如
Just 10
如果类型太通用(这里它将是Num a => Maybe a
),我们可以使用两个连续的冒号(::
)给Haskell一个提示,例如:
Just 10 :: Maybe Int
或者因为我们已经引入了类型别名X
:
Just 10 :: X
对于Maybe来说,x的实例是什么,因为我们通过它10.想知道,如果实例值是10并且类型为Int。
Welll如前所述,Haskell中的类型具有 no 默认构造函数。我们这里有两位候选人:Just n
n
和Int
(如果我们使用类型X
)或Nothing
。所以我们选择其中一个:
Just 10 :: X
Nothing :: X
由于在构造对象后不能更改对象的状态(即Haskell中的所有对象都是不可变的),这意味着默认构造函数设置一些初始数据会很奇怪,然后以后的方法会改变那个对象。
因此,您可以将数据构造函数(此处为Just
和Nothing
)视为标记容器,将容器中的一组参数放在一起,并将其标记为使用了什么构造函数。所以对象的图形视图是:
+------+ +---------+
| Just | | Nothing |
+------+ +---------+
| o |
+---|--+
|
v
+----+
| 10 |
+----+
答案 2 :(得分:2)
当您将代数类型定义写为
时data Maybe a = Nothing | Just a
LHS是一种类型构造表达式(它表明Maybe
具有种类* -> *
),而RHS是一种分离的替代品,每一种都是值构造函数,因此对于类型Maybe a
,Just
是一个一元构造函数,用于创建此类型的对象,Nothing
是一个无效的对象。