本文介绍了为什么没有关于Haskell(与Scala或C#相对)中的协变和反变化的讨论?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道类型的协变和逆变是什么。我的问题是为什么我在研究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#相对)中的协变和反变化的讨论?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 15:24