I'm trying to use typeclasses and functional dependencies to get a type function that can transform say, Int
to Cont Int
in the code below, then use it in another typeclass as shown below.
{-# LANGUAGE KindSignatures, FunctionalDependencies, FlexibleInstances, FlexibleContexts #-}
newtype TestData a b = TestData b
newtype Cont a = Cont a
class TypeConv (repr :: * -> *) a b | repr a -> b where
class Lift repr a where
liftOp :: (TypeConv repr a a') => a -> repr a'
instance TypeConv (TestData a) Int (Cont Int) where
instance Lift (TestData a) Int where
liftOp i = TestData (Cont i)
And here's the error from ghci 7.4.2
src/Test.hs:13:26:
Could not deduce (a' ~ Cont Int)
from the context (Full (TestData a) Int a')
bound by the type signature for
liftOp :: Full (TestData a) Int a' => Int -> TestData a a'
at src/Test.hs:13:5-32
a' is a rigid type variable bound by
the type signature for
liftOp :: Full (TestData a) Int a' => Int -> TestData a a'
at src/Test.hs:13:5
In the return type of a call of `Cont'
In the first argument of `TestData', namely `(Cont i)'
In the expression: TestData (Cont i)
Given that the TypeConv
typeclass has a fundep that I read as: "Given repr
and a
, we can infer b
" and provided an instance for Int
, why can't ghc infer that a' ~ Cont Int
?
TestData
just there to try to make the types work? I'm not sure what you're trying to achieve with it. Do you actually want this instance to createliftOp :: Int -> Cont Int
but you had to wrap it inTestData
? – AndrewCrepr
has no use here. The idea is thatrepr
anda
should both decidea'
inTypeConv
– Chetan