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?
ExpQ
type is just a synonym forQ Exp
. There is no constructor namedExpQ
as you seem to be trying to use here. It’s not clear what you’re trying to achieve, and a full tutorial on how to use Template Haskell is not suitable for Stack Overflow. Based on the misspelled “Symantics” (and several of your previous questions) it looks like you’re trying to follow along with some of Oleg Kiselyov’s writing on staged tagless final interpreters? Could you share what you’re basing this on and how you expect to use the result? – Jon Purdy