将 Haskell 转换为模板 Haskell: 无法匹配预期类型 ExpQ
Converting Haskell to Template Haskell: couldn't match expected type ExpQ
我有以下 Haskell 代码(只是所有代码的一部分,但有效):
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))
我正在尝试将其转换为模板 Haskell。具体来说,我想摆脱 ByteCode,只使用 ExpQ(对我来说是新手)模板 Haskell 类型。所以现在我有:
newtype C a = C ExpQ
unC (C x) = x
我正在尝试更新实例,所以我的新代码是:
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))
但是我收到了很多 Couldn't match expected type 'Q Exp' with actual type 't1 -> (t0, t1)' 错误。我怎样才能最好地编写这个新实例?
在原始的 C
类型中,有一个整数“state”贯穿计算,这意味着 C
新类型实际上包装了一个 function类型:
Int -> (ByteCode t, Int)
表达式:
C (\vc -> ...) -- C constructor takes a function
和
unC e1 vc -- unC e1 gets the function, and it's applied to vc
原代码中反映了这一点。
在你的新 C
类型中,你已经删除了状态,C
新类型只是一个 ExpQ
,但你还没有更新任何代码到反映此更改,因此您会在 ExpQ
(由新 C
包装的类型)和 Int -> (ByteCode t, Int)
形式的函数(由旧 [=14 包装的类型)之间出现类型不匹配错误=]).
您可能会通过以下方式更接近您的预期目标:
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)|]
我有以下 Haskell 代码(只是所有代码的一部分,但有效):
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))
我正在尝试将其转换为模板 Haskell。具体来说,我想摆脱 ByteCode,只使用 ExpQ(对我来说是新手)模板 Haskell 类型。所以现在我有:
newtype C a = C ExpQ
unC (C x) = x
我正在尝试更新实例,所以我的新代码是:
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))
但是我收到了很多 Couldn't match expected type 'Q Exp' with actual type 't1 -> (t0, t1)' 错误。我怎样才能最好地编写这个新实例?
在原始的 C
类型中,有一个整数“state”贯穿计算,这意味着 C
新类型实际上包装了一个 function类型:
Int -> (ByteCode t, Int)
表达式:
C (\vc -> ...) -- C constructor takes a function
和
unC e1 vc -- unC e1 gets the function, and it's applied to vc
原代码中反映了这一点。
在你的新 C
类型中,你已经删除了状态,C
新类型只是一个 ExpQ
,但你还没有更新任何代码到反映此更改,因此您会在 ExpQ
(由新 C
包装的类型)和 Int -> (ByteCode t, Int)
形式的函数(由旧 [=14 包装的类型)之间出现类型不匹配错误=]).
您可能会通过以下方式更接近您的预期目标:
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)|]