Что означает символ => в Haskell?

Я новичок в Haskell и, в общем, для функционального программирования, и мне немного неудобно его синтаксис.

В следующем коде обозначается символ =>? А также (Num a, Ord a)?

loop :: (Num a, Ord a) => a -> (t -> t) -> t -> t

Ответы

Ответ 1

Это ограничение типа класса; (Num a, Ord a) => ... означает, что loop работает с любым типом a, который является экземпляром классов Num и Ord, соответствующих числовым типам и упорядоченным типам соответственно. В принципе, вы можете думать о loop как о типе в правой части =>, за исключением того, что a требуется, чтобы быть экземпляром Num и Ord.

Вы можете думать о типах классов, которые в основном похожи на интерфейсы ООП (но это не одно и то же!) - они инкапсулируют набор определений, которые должен поддерживать любой экземпляр, и общий код может быть написан с использованием этих определений. Например, Num включает числовые операции, такие как сложение и умножение, а Ord включает меньше, больше и т.д.

Для получения дополнительной информации о типах классов см. это введение из Учите вас Haskell.

Ответ 2

=> разделяет две части сигнатуры типа:

  • Слева, ограничения типов
  • Справа фактический тип

Итак, вы можете думать о (Num a, Ord a) => a -> (t -> t) -> t -> t как о значении "тип a -> (t -> t) -> t -> t, а также должен быть экземпляр Num для a и экземпляр Ord для a".

Подробнее о классах см. http://www.learnyouahaskell.com/types-and-typeclasses

Ответ 3

Один из способов подумать о том, что Ord a и Num a являются дополнительными входами в функцию. Это особый вид ввода: словари. При использовании этой функции с определенным типом a также должны быть доступны словари для операций Ord и Num для типа a.

Любая функция, использующая функцию со словарными входами, также должна иметь одинаковые словарные входы.

foo :: (Num a, Ord a) => a -> t
foo x = loop x someFunc someT

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

instance Num MyType with
  x + y = ...
  x - y = ...
  ...

Это создает словарь для операций Num на MyType, поэтому MyType можно использовать везде, где Num a является требуемым входом (при условии, что он удовлетворяет другим требованиям, конечно).

Ответ 4

В левой части => вы объявляете ограничения для типов, которые используются справа.

В приведенном примере это означает, что a ограничивается экземпляром класса типа Ord и класса типа Num.