2015-01-21 3 views
11

При написании контекстов на типе подписи, обычно я хотел бы сделать что-то вродеHaskell Несколько контекстов - каррирование?

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

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

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

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

+0

SPJ представил лекцию, в которой он объяснил, с чем скомпилированы ограничения. https://www.youtube.com/watch?v=6COvD8oynmI - Короче говоря, они являются аргументами функций сами по себе. – AJFarmar

ответ

6

Две версии одинаковы. Ограничения и 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 для ошибок.

+0

Хотя первая должна быть ошибкой анализатора, если следовать грамматике 2010 года строго. Затем, с другой стороны, [парсер GHC] (https://github.com/ghc/ghc/blob/master/compiler/parser/Parser.y) полон вещей, которые я не могу понять. – Zeta

+0

FTR, вот релевантная часть синтаксического анализатора: https://github.com/ghc/ghc/blob/851ed7211fb18fea938be84c99b6389f6762b30d/compiler/parser/Parser.y#L1082 – kirelagin

Смежные вопросы