Haskell 中不同类型之间的关系
Relation Between the Different Types in Haskell
据我了解,Haskell中有4个"types":
- 具有
data
的代数数据类型
数据类型构造函数(data
类型中 =
之后的内容;从技术上讲不是类型,我不认为)
- 输入别名
type
- 类型类
class
- 类型实例
instance
问题是:
- 如果Haskell中的类型更多。如果有,有什么关系。
data
类型和 class
类型类之间的区别。它们看起来很相似,但显然它们有一些不同的特征。与 (3) 相同。
data
类型和 instance
类型类实例之间的区别。
我是 Haskell 的新手。
data
和 newtype
引入新类型(或实际上是类型构造函数 - 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
据我了解,Haskell中有4个"types":
- 具有
data
的代数数据类型
数据类型构造函数(data
类型中=
之后的内容;从技术上讲不是类型,我不认为)- 输入别名
type
- 类型类
class
- 类型实例
instance
问题是:
- 如果Haskell中的类型更多。如果有,有什么关系。
data
类型和class
类型类之间的区别。它们看起来很相似,但显然它们有一些不同的特征。与 (3) 相同。data
类型和instance
类型类实例之间的区别。
我是 Haskell 的新手。
data
和 newtype
引入新类型(或实际上是类型构造函数 - 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 ofShow
) this is a function that takes ana
and returns a string
这个实例看起来像这样
instance Show SomeType where
show SomeConstructor = "SomeConstructor"
这意味着
SomeType
satisfies the constraintShow
, and I'll show you how by providing an implementation ofshow
这就是它的大致要点。有一些语言扩展允许类型 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