Я использую GHCi 7.0.3 со следующей программой, которая реализует список типов:
{-# LANGUAGE TypeOperators #-}
data True
data False
-- List
data Nil
data Cons x xs
-- Type-level infix operator must begin with ':'
data x ::: xs
infixr 5 ::: -- set precedence level to 5 (tight)
Он компилируется, но когда я тестирую его с помощью
:t (undefined :: True:::Nil)
(какой тип undefined
при нажатии на тип True:::Nil
?) Я получаю эту ошибку:
Illegal operator `:::' in type `True ::: Nil'
Use -XTypeOperators to allow operators in types
И действительно, когда я запускаю GHCi с флагом
-XTypeOperators
Я получаю ожидаемый результат:
(undefined :: True ::: Nil) :: True ::: Nil
Мой вопрос: почему не работает эквивалентная прагма:
{-# LANGUAGE TypeOperators #-}
Изменить: Если прагмы не распространяются на среду GHCi, чем на другую загадку. Я пробовал эту программу:
class And b1 b2 b | b1 b2 -> b where
andf :: b1 -> b2 -> b
-- truth table
instance And True True True where andf = undefined
instance And True False False where andf = undefined
instance And False True False where andf = undefined
instance And False False False where andf = undefined
Для этого потребовались следующие прагмы:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
Но после компиляции я мог бы использовать его в GHCi:
*Main> :t andf (undefined::True) (undefined::False)
andf (undefined::True) (undefined::False) :: False
Я предполагаю, что в случае списка интерпретатор не мог даже разобрать выражение с помощью оператора уровня типа :::
, тогда как в случае многопараметрических классов командная строка была подвержена анализу. Но, подумайте об этом, GHCi выполнил вывод типа с использованием многопараметрических классов и функциональных зависимостей, не так ли? Этот тип вывода выполняется в GHCi, а не путем вызова некоторой функции в скомпилированном коде, правильно?