Думайте о forall
как о функции анонимного типа. Все типы данных в Haskell, которые имеют переменные типа в своей сигнатуре типа, неявно имеют forall
. Например, рассмотрим:
f :: a -> Int
f _ = 1
Вышеупомянутая функция f
принимает аргумент любого типа и возвращает Int
. Откуда взялся a
? Он исходит от квантификатора forall
. Следовательно, это эквивалентно:
f :: (forall a . a -> Int)
f _ = 1
Кватификатор forall
может использоваться для любого типа данных, а не только для функций. Например, рассмотрим типы следующих значений:
() :: ()
10 :: Int
pi :: Floating a => a
Здесь ()
и 10
мономорфны (т.е. они могут быть только одного конкретного типа). С другой стороны, pi
полиморфен с ограничением класса типов (т.е. он может быть любого типа, если этот тип является экземпляром Floating
). Явно выписанный тип pi
:
pi :: (forall a . Floating a => a)
Опять же квантификатор forall
действует как функция типа. Он предоставляет вам переменную типа a
. Теперь рассмотрим тип функции g
:
g :: (forall a . a) -> Int
g _ = 1
Здесь g
ожидает аргумент типа forall a . a
и возвращает Int
. По этой причине g ()
не работает: ()
относится к типу ()
, а не к типу forall a . a
. Фактически, единственное значение типа forall a . a
это undefined
:
undefined :: a
Записано явно с forall
:
undefined :: (forall a . a)
Если вы заметили, я всегда заключал forall
количественные показатели в круглые скобки. Причина, по которой я это сделал, состоит в том, чтобы показать вам, что когда вы используете количественное определение forall
для функции, количественное определение распространяется полностью вправо. Это похоже на лямбда: если вы не заключите лямбда в скобки, Haskell расширит лямбда-функцию полностью вправо. Следовательно, тип f
- (forall a . a -> Int)
, а не (forall a . a) -> Int
.
Помните, что в первом случае Haskell ожидает, что тип аргумента будет a
(т.е. что угодно). Однако во втором случае Haskell ожидает, что тип аргумента будет (forall a . a)
(т.е. undefined
). Конечно, если вы попытаетесь оценить undefined
, ваша программа немедленно остановится с ошибкой. К счастью, вы не пытаетесь это оценить.
person
Aadit M Shah
schedule
05.12.2013