Я использую 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 #-}
Edit: Если прагмы не распространяются на среду 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, а не вызовом какой-то функции в скомпилированном коде?