Я пытаюсь определить функцию внутри семейства типов, которая полиморфна фантомному типу самого GADT, определенного в семействе типов.
Мое определение семейства типов выглядит следующим образом:
class Channel t where
data Elem t a :: *
foo :: t -> Elem t a
bar :: Elem t a -> [a]
У меня есть такой пример:
data MyChannelType = Ch
instance Channel MyChannelType where
data Elem MyChannelType a where
MyConstructor :: Char -> Elem MyChannelType Char
foo _ = MyConstructor 'a'
bar (MyConstructor c) = repeat c
Компилятор жалуется, что:
Couldn't match type ‘a’ with ‘Char’
‘a’ is a rigid type variable bound by
the type signature for foo :: MyChannelType -> Elem MyChannelType a
Можно ли написать эту функцию с помощью Rank2Types или переформулировать мои типы данных, чтобы включить ее?
РЕДАКТИРОВАТЬ: в ответ на разъяснения Ганеш запросил
Я бы хотел, чтобы foo (bar Ch) :: [Int]
был незаконным.
Я использовал в точности решение, которое предлагает Ганеш, но меня мотивирует следующий более сложный пример, где он падает; данный:
data MyOtherType = IntCh | StringCh
У меня есть такой пример:
instance Channel MyOtherType where
data Elem MyOtherType a where
ElemInt :: Int -> Elem MyOtherType Int
ElemString :: String -> Elem MyOtherType String
foo IntCh = ElemInt 0
foo StringCh = ElemString "a"
bar (ElemInt i) = repeat i
bar (ElemString s) = repeat s
Большое спасибо,
Майкл
bar (foo Ch) :: [Int]
, чтобы помочь понять варианты его переформулирования? - person GS - Apologise to Monica   schedule 12.08.2014