我知道什么是类型的协变和逆变。我的问题是为什么在学习Haskell时(而不是例如Scala),我还没有遇到这些概念的讨论?
似乎Haskell对类型的看法与Scala或C#有根本性的区别,我想表达这种差异。
或者我可能是错的,我还没有学足够的Haskell :-)
似乎Haskell对类型的看法与Scala或C#有根本性的区别,我想表达这种差异。
或者我可能是错的,我还没有学足够的Haskell :-)
主要有两个原因:
然而,这些概念确实适用——例如,Functor
实例的提升操作由fmap
执行实际上是协变的;在范畴论中,术语协变/逆变用于讨论函子。 contravariant
包为逆变函子定义了一个类型类,如果您查看实例列表,就会看到我为什么说它非常不常见。
这个想法也隐含地出现在手动转换的各个地方——各种数字类型类定义到基本类型(如Integer
和Rational
)的转换,以及模块Data.List
包含一些标准函数的通用版本。如果您查看这些通用版本的类型,您将看到逆变位置上的类型使用Integral
限制(给出toInteger
),而协变位置上使用Num
限制(给出fromInteger
)。
Ord
和Eq
(当然它们的等效物),它们甚至都没有数据可以被改变。 - Daniel C. SobralNum
和 Integral
是如此对偶的! - J. AbrahamsonOption[+A]
的类,带有子类Some[+A]
和None
。你必须提供协变注释+
来表示如果Foo extends Bar
,那么Option[Foo]
是Option[Bar]
。由于存在子类型,这是必需的。在Haskell中,不存在子类型。在Haskell中,称为Maybe
的Option
等效类型有以下定义:data Maybe a = Nothing | Just a
类型变量a
只能是一种类型,因此不需要更多关于它的信息。