无法找出 Haskell 中的正确类型
我正在制作一个基于堆栈的伪汇编程序虚拟机。以下是问题函数中使用的一些自定义类型:
type Program = Array Int Opcode
type Labels = Map String Int
type Stack = [Integer]
type Memory = Map String Integer
type VarList = [(String, Integer)]
这是问题函数;还有大约 20 个其他情况,但我只会列出与此问题相关的 3 个情况:
runFrom :: Int -> Program -> VarList -> String
runFrom i p vars = step i [] (fromList vars) [] where
labels = labelMap p
step i stack mem out =
case ((Array.!) p i, stack) of
(CALL name, s) -> step ((Map.!) labels name) ((i+1):s) mem out
(INT n, s) -> step (i+1) (n:s) mem out
(J name, s) -> step ((Map.!) labels name) s mem out
首先,问题是“CALL”情况;当“CALL”被注释掉时,其他两种情况工作正常。为了清楚起见,“INT Integer”将 Integer 压入堆栈,“J String”无条件跳转到映射到 String 名称的指令。 “CALL String”应该将下一条指令的索引(i+1)压入堆栈并无条件跳转到标签名称。但是,如果我尝试加载上面的代码,GHC 会抱怨无法将预期的 Integer 类型与“INT”情况下步骤的第二个参数中推断的 Int 类型进行匹配。由于当“CALL”被注释掉时“INT”工作正常,我假设 CALL 中发生了一些奇怪的事情(也许是 ((i+1):s) ?)。有人可以帮我修复 CALL 问题吗?
I'm making a stack based pseudo-assembler virtual machine. Here are some custom types used in the problem function:
type Program = Array Int Opcode
type Labels = Map String Int
type Stack = [Integer]
type Memory = Map String Integer
type VarList = [(String, Integer)]
Here's the problem function; there are about 20 other cases, but I'm only going to put the 3 that seem relevant to this problem:
runFrom :: Int -> Program -> VarList -> String
runFrom i p vars = step i [] (fromList vars) [] where
labels = labelMap p
step i stack mem out =
case ((Array.!) p i, stack) of
(CALL name, s) -> step ((Map.!) labels name) ((i+1):s) mem out
(INT n, s) -> step (i+1) (n:s) mem out
(J name, s) -> step ((Map.!) labels name) s mem out
First of all, the problem is the "CALL" case; the other two cases work fine when "CALL" is commented out. For the sake of clarity, "INT Integer" pushes an Integer onto the stack, and "J String" unconditionally jumps to the instruction that is mapped to the String name. "CALL String" is supposed to push onto the stack the index of the next instruction (i+1) and unconditionally jump to the label name. However, if I try to load the code above, GHC complains about not being able to match the expected Integer type against the inferred Int type in second argument of step for the "INT" case. Since "INT" works fine when "CALL" is commented out, I assume something screwy is going on in CALL (perhaps the ((i+1):s) ?). Can someone help me fix CALL?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的
Int
和Integer
不一致...如果出于某种特定原因您需要在不同情况下使用两者,并且还需要从一种转换为另一种,请使用fromIntegral
作为显式转换。否则就选择一个(可能是Int
)。Your
Int
s andInteger
s are inconsistent... If there's some specific reason you need to use both in different situations, and also to convert from one to the other, usefromIntegral
as an explicit conversion. Otherwise just settle on one (probablyInt
).因为
type Labels = Map String Int
,所以标签映射到Int
,而Stack
、Memory
和VarList
使用整数
。CALL
强制step
的第一个参数为Int
,这与INT
和INT
的使用不一致代码>JBecause
type Labels = Map String Int
so labels map toInt
whereasStack
,Memory
, andVarList
useIntegers
.CALL
forces the first argument ofstep
to be anInt
which is at odds with the use ofINT
andJ