Семейство закрытых типов и тип вывода в Haskell
В GHC-7.7 (и 7.8) были введены семейства замкнутого типа:
Семейство замкнутого типа имеет все свои уравнения, определенные в одном месте и не может быть продлен, тогда как у открытого семейства могут быть случаи распространения через модули. Преимущество замкнутого семейства состоит в том, что его уравнения в порядке, аналогично определению функции уровня термина
Я хочу спросить вас, почему следующий код не компилируется? GHC должен иметь возможность выводить все типы - GetTheType
определяется только для типа X
, и если мы закомментируем выделенную строку, компиляция кода.
Является ли это ошибкой в GHC или семействах закрытого типа, не имеет такой оптимизации YET?
код:
{-# LANGUAGE TypeFamilies #-}
data X = X
type family GetTheType a where
GetTheType X = X
class TC a where
tc :: GetTheType a -> Int
instance TC X where
tc X = 5
main = do
-- if we comment out the following line, the code compiles
let x = tc X
print "hello"
И ошибка:
Couldn't match expected type ‛GetTheType a0’ with actual type ‛X’
The type variable ‛a0’ is ambiguous
In the first argument of ‛tc’, namely ‛X’
In the expression: tc X
Ответы
Ответ 1
Нет ничего плохого в закрытых типах семейств. Проблема в том, что функции типа не являются инъективными.
Скажем, вы могли бы иметь эту закрытую функцию типа:
data X = X
data Y = Y
type family GetTheType a where
GetTheType X = X
GetTheType Y = X
вы не можете вывести тип аргумента из типа результата X
.
Семейства данных являются инъективными, но не закрытыми:
{-# LANGUAGE TypeFamilies #-}
data X = X
data family GetTheType a
data instance GetTheType X = RX
class TC a where
tc :: (GetTheType a) -> Int
instance TC X where
tc RX = 5
main = do
let x = tc RX
print "hello"