根据我的理解,Haskell中有4种“类型”:
data
=
类型中data
之后的内容;技术上不是类型,我不认为)type
class
instance
问题是:
data
类型和class
类型类之间的区别。它们看似相似,但显然它们有一些不同的特征。与(3)相同。data
类型和instance
类型类实例之间有何区别。我是Haskell的新手。
答案 0 :(得分:6)
data
和newtype
会引入新类型(或实际类型构造函数 - Maybe
不是类型,但Maybe a
是任何a
的类型这是一种类型。)
data
声明引入了一种新类型(=
的左侧)以及表示该类型数据的方式(=
的右侧)。
例如,如果您有这样的数据声明:
data SomeType = SomeConstructor
然后你引入了一个名为SomeType
的新类型,以及一种构造SomeType
值的方法,即构造函数SomeConstructor
(顺便提一下,它没有任何参数,所以是这种类型的唯一价值)。
类型类没有 这些东西(instance
也没有)。类型类引入了一个约束和一堆多态函数,如果满足该约束,它们应该是可用的。 instance
基本上是通过为这些函数提供实现来说“此类型满足此约束”。所以class
并没有真正引入新类型,它只是为现有类型提供ad-hoc多态的一种方式。
例如,Show
类型类似于:
class Show a where -- a is an instance of Show if
show :: a -> String -- it has a function called show with this signature
(请注意,Show
中的实际Prelude
课程
show
现在有Show a => a -> String
类型,您可以将其视为
对于所有a,如果它们满足约束
Show
(或者,如果它们是Show
的实例),则这是一个函数,它接受a
并返回一个字符串< / p>
此实例看起来像这样
instance Show SomeType where
show SomeConstructor = "SomeConstructor"
这意味着
的实现向您展示
SomeType
满足约束Show
,我将通过提供show
这大致是它的要点。有一些语言扩展允许类型类和实例发生更多相关事情,但您现在不必担心这一点。
答案 1 :(得分:3)
您可能听说过种,它们是Haskell中的“类型类型”。类型是类*
的类型,它表示可以具有值的内容:
> :kind Int
Int :: *
> :kind Char
Char :: *
类型构造函数是具有类* -> *
的东西;类型构造函数采用一种类型(某种类型*
)并返回另一种类型。
> :kind Maybe
Maybe :: * -> *
> :kind []
[] :: * -> *
应用类型构造函数会为您提供一种新的*
:
> :kind Maybe Int
Maybe Int :: *
> :kind [] Float
[] Float :: *
(解析器允许[Foo]
作为[] Foo
的特例。)
还有其他类型的东西。其中一个是Constraint
,您使用约束构造函数(也称为类型类)创建Constraint
。给一个约束构造函数一个类型,然后你得到一个约束。
> :kind Show
Show :: * -> Constraint
> :kind Show Int
Show Int :: Constraint
> :kind Show (Int -> Char)
Show (Int -> Char) :: Constraint
(请注意,即使没有定义Int -> Char
的实例,也会对后者进行适当的处理。)
在这种情况下,=>
看起来像一个运算符,而不仅仅是特殊的语法。它的参数是约束的“列表”(尽管使用普遍量化的类型变量而不是具体类型)和类型,其返回值是“约束”类型(让我们假装除了ConstrainedType
之外还有*
,* -> *
和Constraint
)。
:t show
show :: Show a => a -> String
-- Taking extreme liberties with syntax
-- :k (=>)
-- (=>) :: [Constraint] -> * -> ConstrainedType
-- A section?
-- :k (Show a =>)
-- (Show a =>) :: * -> ConstrainedType
-- :k (Showa => * -> String)
-- Show a => a -> String :: ConstrainedType