Eri*_*ikR 56 haskell covariance contravariance
我知道类型的协方差和逆变.我的问题是为什么我在Haskell的研究中没有遇到过这些概念的讨论(与Scala相反)?
看起来Haskell查看类型的方式与Scala或C#相比存在根本区别,我想阐明这种区别是什么.
或者也许我错了,我还没有学到足够的Haskell :-)
C. *_*ann 60
主要有两个原因:
然而,这些概念做应用-例如,通过进行起重作业fmap的Functor情况下,实际上是协变; 术语共同/逆变在类别理论中用于谈论仿函数.该contravariant包为逆变函子定义了一个类型类,如果你查看实例列表,你会明白为什么我说它不太常见.
还有一些地方的想法隐含显示出来,在手动转换如何工作-各种数字型类定义的转换和从基本类型,如Integer和Rational,模块Data.List包含的一些标准功能的通用版本.如果查看这些泛型版本的类型,您会看到Integral约束(赋予toInteger)用于逆变位置的类型,而Num约束(赋值fromInteger)用于协变位置.
dfl*_*str 21
Haskell中没有"子类型",所以协方差和逆变没有任何意义.
在Scala中,您有例如Option[+A]子类Some[+A]和None.你必须提供协方差注释+来表明a Option[Foo]是一个Option[Bar]if Foo extends Bar.由于存在子类型,这是必要的.
在Haskell中,没有子类型.OptionHaskell中的等价物称为Maybe:
data Maybe a = Nothing | Just a
Run Code Online (Sandbox Code Playgroud)
类型变量a只能是一种类型,因此不需要有关它的更多信息.
如上所述,Haskell没有子类型.但是,如果您正在查看类型类,可能不清楚如何在没有子类型的情况下工作.
类型类指定谓词,而不是类型本身.因此,当Typeclass有一个超类(例如Eq a => Ord a)时,这并不意味着实例是子类型,因为只有谓词是继承的,而不是类型本身.
此外,共同,反对和方差在不同的数学领域意味着不同的东西(见维基百科).例如,covariant和contravariant这两个术语用于仿函数(后者又用于Haskell),但这些术语意味着完全不同的东西.术语不变量可以在很多地方使用.