无法弄清楚Haskell中的正确类型

时间:2011-10-27 01:41:47

标签: 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抱怨无法在“INT”情况下的步骤的第二个参数中将预期的Integer类型与推断的Int类型匹配。因为当“CALL”被注释掉时“INT”工作正常,我假设在CALL中发生了一些棘手的问题(也许是((i + 1):s)?)。有人可以帮我修理CALL吗?

2 个答案:

答案 0 :(得分:6)

您的IntInteger不一致......如果您有某些特定原因需要在不同情况下使用它们,并且还要从一个转换为另一个,请使用{{1作为显式转换。否则只需坚持一个(可能是fromIntegral)。

答案 1 :(得分:3)

因为type Labels = Map String Int所以标签映射到Int,而StackMemoryVarList使用IntegersCALL强制step的第一个参数为Int,这与使用INTJ

不一致