Когда (если вообще) можно ли частично применять синонимы типа?

Видимо, немного рассеянно, я написал что-то вроде следующего:

{-# LANGUAGE ConstraintKinds     #-}
{-# LANGUAGE TypeFamilies        #-}

class Foo f where
  type Bar f :: *
  retbar :: Bar f -> IO f

type Baz f = (Foo f, Eq f)

  -- WithBar :: * -> (*->Constraint) -> * -> Constraint
type WithBar b c f = (c f, Bar f ~ b)

instance Foo () where
  type Bar () = ()
  retbar = return

naim :: WithBar () Baz u => IO u  -- why can I do this?
naim = retbar ()

main = naim :: IO ()

Только после успешной компиляции я понял, что на самом деле это не должно работать: Baz определяется как синоним типа с одним аргументом, но здесь я использую его без прямого аргумента. Обычно GHC лает на меня Type synonym ‘Baz’ should have 1 argument, but has been given none когда я пытаюсь что-то подобное.

Не поймите меня неправильно: мне бы очень хотелось написать это, и достаточно просто увидеть, как это может работать в этом конкретном примере (просто WithBar даст подпись naim :: (Foo u, Bar u ~ ()) => IO u, что, конечно, хорошо), но что я не понимаю, почему это на самом деле так работает здесь. Это возможно только ошибка в ghc-7.8.2 разрешить это?

3 ответа

Ваш файл компилируется в GHC 7.8, но в GHC 7.10 я получаю ошибку:

Синоним типа 'Baz' должен иметь 1 аргумент, но ему не дано ни одного

В сигнатуре типа для 'naim': naim:: WithBar () Baz u => IO u

Добавление -XLiberalTypeSynonyms исправляет ошибку. Поэтому это ошибка в 7.8.

Частичное приложение должно быть включено LiberalTypeSynonyms расширение.

По сути, это откладывает большую часть проверки согласованности синонимов типов до тех пор, пока они не будут расширены, поэтому ваше "встроенное" объяснение по сути является правильной идеей.

Странная вещь здесь, однако, в том, что это расширение не подразумевается теми, что в вашем модуле. Я только что проверил, и частичное приложение не работает вообще с просто ConstraintKinds, TypeFamilies а также PolyKinds, (Я добавил последний, потому что виды проверяются перед расширением, и в противном случае мои типы тестов были выведены неверно.)

Тем не менее, ваш файл прекрасно загружается для меня в GHCi 7.8.3. Может быть, это какая-то ошибка, даже если есть расширение, чтобы сделать его правильно легальным.

Я не знаю, каковы официальные правила, но для такого рода вещей кажется разумным работать на основе стратегии расширения синонимов крайнего левого типа. Единственное, что имеет значение, это то, что синонимы типа могут быть удалены в отдельной и завершающей фазе, прежде чем произойдет остальная проверка типов. Я не знаю, предполагается ли, что вы можете использовать частично примененный синоним типа F в качестве аргумента синонима другого типа G, если только G гарантирует, что F получает пропущенные аргументы, но это, безусловно, согласуется с идеей, что синонимы типа мелкое удобство.

Другие вопросы по тегам