I am trying to define a function within a type family that is polymorphic in the phantom type of the GADT itself defined in the type family.
Determining my family type is done by line:
class Channel t where data Elem ta :: * foo :: t -> Elem ta bar :: Elem ta -> [a]
I have an instance as follows:
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
The compiler complains that:
Couldn't match type 'a' with 'Char' 'a' is a rigid type variable bound by the type signature for foo :: MyChannelType -> Elem MyChannelType a
Is it possible to write this function using Rank2Types or reformulate my data types to include it?
EDIT : in response to clarification, Ganesha requested
I would like foo (bar Ch) :: [Int] be illegal.
I use exactly the solution that Ganesh offers, but I am motivated by the following more complex example, where it falls; Given:
data MyOtherType = IntCh | StringCh
I have an instance as follows:
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
Many thanks,
Michael
source share