问题描述
我知道类型的协变和逆变是什么。我的问题是为什么我在研究Haskell(而不是Scala)时还没有遇到这些概念的讨论?
看起来有一个基础Haskell视图类型与Scala或C#不同,我想说明它们之间的区别。
或者我错了,我只是Haskell has not have enough enough: - )
有两个主要原因:
- Haskell缺乏子类型的固有概念,所以一般情况下方差不太相关。
- 逆变大多出现在涉及可变性的地方,所以大多数Haskell中的数据类型只会是协变的,并且显式地区分它们几乎没有什么价值。
然而,例如,对于 Functor
实例,由 fmap
执行的提升操作实际上是协变的;在类别理论中使用术语co- / contravariance来讨论函子。 定义了一个类型类如果你看一下实例列表,你会明白为什么我说它不太常见。
也有一些地方可以隐含地显示这个想法,在如何进行手动转换 - 各种数字类型类定义了基本类型转换,如 Integer
和 Rational
,以及模块 Data.List
包含一些标准函数的通用版本。如果您查看,您会看到 Integral
约束(给出 toInteger
)用于类型在逆变位置, Num
约束(给出 fromInteger
)用于协变位置。
I know what covariance and contravariance of types are. My question is why haven't I encountered discussion of these concepts yet in my study of Haskell (as opposed to, say, Scala)?
It seems there is a fundamental difference in the way Haskell views types as opposed to Scala or C#, and I'd like to articulate what that difference is.
Or maybe I'm wrong and I just haven't learned enough Haskell yet :-)
There are two main reasons:
- Haskell lacks an inherent notion of subtyping, so in general variance is less relevant.
- Contravariance mostly appears where mutability is involved, so most data types in Haskell would simply be covariant and there'd be little value to distinguishing that explicitly.
However, the concepts do apply--for instance, the lifting operation performed by fmap
for Functor
instances is actually covariant; the terms co-/contravariance are used in Category Theory to talk about functors. The contravariant
package defines a type class for contravariant functors, and if you look at the instance list you'll see why I said it's much less common.
There are also places where the idea shows up implicitly, in how manual conversions work--the various numeric type classes define conversions to and from basic types like Integer
and Rational
, and the module Data.List
contains generic versions of some standard functions. If you look at the types of these generic versions you'll see that Integral
constraints (giving toInteger
) are used on types in contravariant position, while Num
constraints (giving fromInteger
) are used for covariant position.
这篇关于为什么没有关于Haskell(与Scala或C#相对)中的协变和反变化的讨论?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!