Что означает символ => в 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
.