Reputation: 139
I had the following Haskell code (just a fragment of all code, but works):
data ByteCode t where
INT :: Int -> ByteCode Int
BOOL:: Bool -> ByteCode Bool
Add :: ByteCode Int -> ByteCode Int -> ByteCode Int
Mul :: ByteCode Int -> ByteCode Int -> ByteCode Int
newtype C t = C (Int -> (ByteCode t, Int))
unC (C t) = t
instance Symantics C where
int x = C(\vc -> (INT x, vc))
bool b = C(\vc -> (BOOL b, vc))
add e1 e2 = C(\vc -> let (e1b,vc1) = unC e1 vc
(e2b,vc2) = unC e2 vc1
in (Add e1b e2b,vc2))
mul e1 e2 = C(\vc -> let (e1b,vc1) = unC e1 vc
(e2b,vc2) = unC e2 vc1
in (Mul e1b e2b,vc2))
I am trying to convert it to Template Haskell. Specifically I wanted to get rid of the ByteCode and just use ExpQ (new to me) Template Haskell type. So now I have:
newtype C a = C ExpQ
unC (C x) = x
I'm trying to update the instance, so my new code is:
newtype C t = C ExpQ
unC (C t) = t
instance Symantics C where
int x = C(\vc -> (ExpQ x, vc))
bool b = C(\vc -> (ExpQ b, vc))
add e1 e2 = C(\vc -> let (e1b,vc1) = unC e1 vc
(e2b,vc2) = unC e2 vc1
in (Add e1b e2b,vc2))
But I am getting a lot of Couldn't match expected type ‘Q Exp’ with actual type ‘t1 -> (t0, t1)’ errors. How can I best write this new instance?
Upvotes: 1
Views: 156
Reputation: 50819
In the original C
type, there was an integer "state" threaded through the computation, meaning that the C
newtype actually wrapped a function of type:
Int -> (ByteCode t, Int)
The expressions:
C (\vc -> ...) -- C constructor takes a function
and
unC e1 vc -- unC e1 gets the function, and it's applied to vc
in the original code reflected this.
In your new C
type, you've removed the state, and the C
newtype is just an ExpQ
, but you haven't updated any of the code to reflect this change, so you are getting type mismatch errors between ExpQ
(the type wrapped by your new C
) and functions of the form Int -> (ByteCode t, Int)
(the type wrapped by the old C
).
You might get closer to your intended goal with something like:
instance Symantics C where
int x = C $ litE (IntegerL (fromIntegral x))
bool False = C [|False|]
bool True = C [|True|]
add e1 e2 = C [|$(unC e1) + $(unC e2)|]
Upvotes: 1