Haskell Несколько контекстов - currying?

При написании контекстов на сигнатуре типа обычно я делаю что-то вроде

f :: (Enum a, Ord a) => a -> a

Но благодаря чистой глупости я обнаружил, что это компилируется и, похоже, работает одинаково, по крайней мере, в GHC 7.8:

f :: Enum a => Ord a => a -> a

Каковы теоретические или практические различия между ними? Является ли второй менее ортодоксальным? отчет Haskell, похоже, не упоминает о второй форме, и я никогда не видел, чтобы она использовалась где угодно. Связанный с нами вопрос.

Ответы

Ответ 1

Две версии одинаковы. Ограничения и forall -s выплывают в верхнюю часть области, когда они еще не существуют. Например, допустимы следующие определения:

foo :: a -> a -> Num a => a
foo = (+)

bar :: a -> forall b. b -> a
bar = const

Но :t foo выводит Num a => a -> a -> a и :t bar выводит a -> b -> a (что эквивалентно forall a b. a -> b -> a).

GHC не поддерживает типы полиморфных возвратов, поэтому ограничения и кванторы выплывают. Я предполагаю, что это мог быть также правильный выбор дизайна для GHC для ошибок.