Судя по всему, Haskell разрешает указывать в левой части декларации типа-синонима type variables, которые не используются в правой части. Это может приводить к интересным эффектам, которые по разному проявляются в GHC и Hugs. Было бы интересно узнать, какое поведение является правильным согласно haskell 98 report.
1)
type F a = Int
class A a where
foo :: A b => a (F b)
GHC — OK
Hugs — Illegal type "F b" in constructor application
2)
type F a = Int
class A a where
foo :: F a
instance A Bool where
foo = 1
instance A Char where
foo = 2
xs = [foo :: F Bool, foo :: F Char]
GHC:
M.hs:14:6:
Ambiguous type variable `a' in the constraint:
`A a' arising from a use of `foo' at M.hs:14:6-8
Probable fix: add a type signature that fixes these type variable(s)
M.hs:14:21:
Ambiguous type variable `a1' in the constraint:
`A a1' arising from a use of `foo' at M.hs:14:21-23
Probable fix: add a type signature that fixes these type variable(s)
Hugs: [1,2]
N>Судя по всему, Haskell разрешает указывать в левой части декларации типа-синонима type variables, которые не используются в правой части. Это может приводить к интересным эффектам, которые по разному проявляются в GHC и Hugs. Было бы интересно узнать, какое поведение является правильным согласно haskell 98 report.
Это уже порядок раскрытия синонимов, как ты сам можешь убедиться. Hugs раскрывает сразу, ghc откладывает.
Лучше такими делами не пользоваться.
Но сама идея
фантомных типов удобна. Особенно, когда используешь GADT. Но и без неё тоже неплохо: data DBIndex ty = DBIndex Int, data Man = ..., type ManIndex = DBIndex Man...