Haskell 中不同类型之间的关系

Relation Between the Different Types in Haskell

据我了解,Haskell中有4个"types":

问题是:

  1. 如果Haskell中的类型更多。如果有,有什么关系。
  2. data 类型和 class 类型类之间的区别。它们看起来很相似,但显然它们有一些不同的特征。与 (3) 相同。
  3. data 类型和 instance 类型类实例之间的区别。

我是 Haskell 的新手。

datanewtype 引入新类型(或实际上是类型构造函数 - Maybe 不是类型,但 Maybe a 是任何 a 那是一种类型)。

data 声明引入了一种新类型(= 的左侧)和表示该类型数据的方法(= 的右侧)。

例如,如果您有这样的数据声明:

data SomeType = SomeConstructor

然后你引入了一个名为 SomeType 的新类型,以及一种构造 SomeType 值的方法,即构造函数 SomeConstructor(顺便说一下,它没有任何参数,所以是居住在这种类型的唯一价值)。

A 类型class 不会 这些事情(instance 也不会)。 typeclass 引入了 constraint 和一堆多态函数,如果满足该约束,这些函数应该可用。 instance 基本上是通过为这些函数提供实现来表示 "this type meets this constraint"。所以 class 并不是真正引入新类型,它只是为现有类型提供临时多态性的一种方式。

例如Show类型class大致是这样的:

class Show a where -- a is an instance of Show if
   show :: a -> String -- it has a function called show with this signature

(请注意 Prelude 中的实际 Show class 并不 相当 看起来像这样)

show 现在具有类型 Show a => a -> String,您可以将其读作

for all a, if they meet the constraint Show (or alternatively, if they are an instance of Show) this is a function that takes an a and returns a string

这个实例看起来像这样

instance Show SomeType where
  show SomeConstructor = "SomeConstructor"

这意味着

SomeType satisfies the constraint Show, and I'll show you how by providing an implementation of show

这就是它的大致要点。有一些语言扩展允许类型 classes 和实例发生更多复杂的事情,但你现在不需要担心。

你可能听说过种类,也就是Haskell中的"types of types"。类型是具有种类 * 的东西,它表示可以具有值的东西:

> :kind Int
Int :: *
> :kind Char
Char :: *

类型构造函数是有种类的东西* -> *;类型构造函数接受一个类型(某种类型 *)和 return 另一种类型。

> :kind Maybe
Maybe :: * -> *
> :kind []
[] :: * -> *

应用类型构造器给你一种新的东西*:

> :kind Maybe Int
Maybe Int :: *
> :kind [] Float
[] Float :: *

(解析器允许 [Foo] 作为 [] Foo 的特例。)

还有其他种类的东西。其中之一是 Constraint,您使用约束构造函数(也称为类型 class)创建了一个 Constraint。给约束构造函数一个类型,你就会得到一个约束。

> :kind Show
Show :: * -> Constraint
> :kind Show Int
Show Int :: Constraint
> :kind Show (Int -> Char)
Show (Int -> Char) :: Constraint

(请注意,即使没有定义 Int -> Char 的实例,后者也是正确类型的。)


从这个角度来看,=> 看起来更像是一个运算符,而不仅仅是特殊的语法。它的参数是一个 "list" 约束(尽管使用通用量化类型变量而不是具体类型)和一个类型,它的 return 值是一个 "constrained" 类型(让我们假设有一种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