Подтвердить что ты не робот

Почему в Haskell нет много дискуссий о совпадении и противоречивости (в отличие от Scala или С#)?

Я знаю, что такое ковариация и контравариантность типов. Мой вопрос: почему я не столкнулся с обсуждением этих понятий еще в моем исследовании Haskell (в отличие от, скажем, Scala)?

Кажется, существует фундаментальное различие в том, как Haskell рассматривает типы в отличие от Scala или С#, и я хотел бы сформулировать, что это за разница.

Или, может быть, я ошибаюсь, и я еще недостаточно изучил Haskell: -)

4b9b3361

Ответ 1

Существуют две основные причины:

  • Haskell не имеет неотъемлемого понятия подтипирования, поэтому в целом дисперсия менее актуальна.
  • Контравариантность в основном появляется там, где задействована мутация, поэтому большинство типов данных в Haskell просто были бы ковариантными, и было бы мало смысла выделять это явно.

Однако эти концепции применимы - например, операция подъема, выполняемая экземплярами fmap для Functor, фактически ковариантна; термины co-/contravariance используются в Теории Теории, чтобы говорить о функторах. Пакет contravariant определяет класс типа для контравариантных функторов, и если вы посмотрите на список экземпляров, вы поймете, почему я сказал это намного меньше общее.

Существуют также места, где идея проявляется неявно в том, как работают ручные преобразования - различные классы числового типа определяют преобразования и из основных типов, таких как Integer и Rational, а модуль Data.List содержит общие версии некоторых стандартных функций. Если вы посмотрите на типы этих общих версий, вы увидите, что ограничения Integral (предоставление toInteger) используются для типов в контравариантных, в то время как ограничения Num (предоставление fromInteger) используются для ковариантной позиции.

Ответ 2

В Haskell нет "подтипов", поэтому ковариация и контравариантность не имеют никакого смысла.

В Scala у вас есть, например, Option[+A] с подклассами Some[+A] и None. Вы должны предоставить аннотации ковариации +, чтобы сказать, что Option[Foo] является Option[Bar], если Foo extends Bar. Из-за наличия подтипов это необходимо.

В Haskell нет подтипов. Эквивалент Option в Haskell, называемый Maybe, имеет это определение:

data Maybe a = Nothing | Just a

Тип переменной a может быть только одним типом, поэтому дополнительная информация о ней не требуется.

Ответ 3

Как уже упоминалось, у Haskell нет подтипов. Однако, если вы смотрите на классные классы, может быть неясно, как это работает без подтипирования.

Typeclasses задают предикаты по типам, а не самим типам. Поэтому, когда Typeclass имеет суперкласс (например, Eq a = > Ord a), это не означает, что экземпляры являются подтипами, поскольку наследуются только предикаты, а не сами типы.

Кроме того, ко-, противопоставление и инвариантность означают разные вещи в разных областях математики (см. Википедию). Например, члены, ковариантные и контравариантные, используются в функторах (которые, в свою очередь, используются в Haskell), но термины означают нечто совершенно иное. Термин "инвариант" можно использовать во многих местах.