вики-страница Haskell на Rank-N-Types сообщает, что этот тип
forall a . a -> (forall b . b -> a)
имеет ранг 1. Я верю в этот факт, и он кажется мне вполне понятным (имея в виду то, что я уже знаю о том, как определить ранг функции). Однако, когда я пытаюсь написать следующий код:
{-# LANGUAGE ExplicitForAll #-}
foo :: forall a . a -> (forall b . b -> a)
foo = undefined
он не компилируется (ghc 8.0.1), что приводит к следующей ошибке:
• Illegal polymorphic type: forall b. b -> a
Perhaps you intended to use RankNTypes or Rank2Types
• In the type signature:
foo :: forall a. a -> (forall b. b -> a)
Вот мне интересно: действительно ли тип foo
имеет Ранг-2? Или у GHC просто нет какого-то умного механизма для определения истинного ранга функции? Иногда в образовательных целях я хочу иметь некоторую команду ghci
, например rank
, для проверки истинных рангов типов функций...
ghci> :rank foo
foo :: forall a . a -> (forall b . b -> a) -- Rank 1
forall
не является зарезервированным символом. Чтобы использовать его в качестве явного квантификатора, требуется одно из этих двух языковых расширений, даже если типы, которые вы хотите написать, имеют ранг 1. Типы ранга 1 обычно имеют эквивалентную форму, в которой квантификаторы можно оставить неявными, отсюда и эта проблема: ожидание что вы включаете явныйforall
только в том случае, если хотите подняться выше ранга 1, где он вам действительно нужен. - person pigworker   schedule 18.12.2016-XExplicitForAll
. Я просто ожидал, что это расширение будет работать как что-то вроде гипотетического-XRank1Types
, где всеforall
должны быть подняты, если это возможно. Судя по всему, в последнем руководстве пользователя ghc ничего не говорится о таком поведении: количественная оценка для всех" rel="nofollow noreferrer">downloads.haskell.org/~ghc/latest/docs/html/users_guide/ - person Shersh   schedule 18.12.2016