无法找出 Haskell 中的正确类型

发布于 2024-12-11 20:47:27 字数 996 浏览 0 评论 0原文

我正在制作一个基于堆栈的伪汇编程序虚拟机。以下是问题函数中使用的一些自定义类型:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

萌无敌 2024-12-18 20:47:27

您的 IntInteger 不一致...如果出于某种特定原因您需要在不同情况下使用两者,并且还需要从一种转换为另一种,请使用fromIntegral 作为显式转换。否则就选择一个(可能是Int)。

Your Ints and Integers 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, use fromIntegral as an explicit conversion. Otherwise just settle on one (probably Int).

予囚 2024-12-18 20:47:27

因为 type Labels = Map String Int,所以标签映射到 Int,而 StackMemoryVarList 使用整数CALL 强制 step 的第一个参数为 Int,这与 INTINT 的使用不一致代码>J

Because type Labels = Map String Int so labels map to Int whereas Stack, Memory, and VarList use Integers. CALL forces the first argument of step to be an Intwhich is at odds with the use of INT and J

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文