【问题标题】:Confusing Error from type matching (I think) - Haskell来自类型匹配的令人困惑的错误(我认为) - Haskell
【发布时间】:2022-01-22 08:53:59
【问题描述】:

遇到一个我无法理解的错误

基本上我的程序应该对自定义数据类型“配置”执行操作

type Vname = String
type Val = Int
type State = [(Vname, Val)]

data Instr =
        LOADI Int
        | LOAD Val
        | ADD
        | STORE Val
        | JMP Int
        | JMPLESS Int
        | JMPGE Int
        deriving (Eq, Read, Show)

data Stack = Stack [Int]
type Config = (Int, State, Stack)

iexec :: Instr -> Config -> Config
iexec (LOADI n) c = do {
        (x,y,z) <- c 
        ;return ( x+1, y, x )
}

我只尝试执行“LOADI”指令之一,但无论我如何更改,我都会收到错误:

    • Couldn't match expected type ‘Stack’
                  with actual type ‘(c1, b0, c0)’
    • In the pattern: (x, y, z)
      In a stmt of a 'do' block: (x, y, z) <- c
      In the expression:
        do (x, y, z) <- c
           return (x + 1, y, x)
   |
42 |         (x,y,z) <- c 
   |         ^^^^^^^

Stack 只是一个 Int 的列表,但我必须以这种方式实现它

什么是 (c1, b0, c0),为什么我的配置元组的第三个值与其他值不一样?

任何帮助将不胜感激!

【问题讨论】:

  • 您的问题是使用 do 表示法,但实际上并未使用 monad。 do ...let ... in ... 你明白吗?
  • 您正在使用单子 do 表示法,但您的类型不涉及任何单子。解决方案:不要使用do,不要使用return,以及任何其他与monad 相关的东西。例如,iexec (LOADI n) (x,y,z) =(x+1,y,z) 类型检查并接近您的代码。 (不过,我认为这不是您真正需要的)
  • 更令人困惑的是(Int, State, Stack)一个Monad实例,它使s &lt;- c成为一种提取堆栈组件的方法元组。
  • @chepner 好点,但我认为这失败了,因为Int 不是一个幺半群。这无助于生成良好的错误消息。
  • 是的,Stack(x, y, z) 的匹配失败首先发生,所以这就是你得到错误的地方。

标签: haskell compiler-errors


【解决方案1】:
iexec :: Instr -> Config -> Config

好的,所以iexec 接受两个参数并返回一个Config(一个元组)。

iexec (LOADI n) c = do 

哦,但这说iexec 接受两个参数并以Monad m =&gt; m a 的形式返回一些东西(通常是初学者的IO,但并非总是如此)。

你不想要do 符号在这里 - 你根本没有做一个单子操作,只是一个纯粹的非单子计算。为此,如果您需要中间值,则应使用 let ... in ...,如果不需要,则仅使用结果表达式:

iexec :: Instr -> Config -> Config
iexec (LOADI n) (x,y,z) = (x+1, y, x)

或者考虑等价的:

iexec :: Instr -> Config -> Config
iexec (LOADI n) (x,y,z) =
    let newPC = x+1
        newState = y
        newStack = x
    in (newPC, newState, newStack)

当然,newStack 的值是 x 根本不起作用,因为堆栈不是 Int,但这只是匹配您的原始代码。

【讨论】:

    猜你喜欢
    • 2012-09-12
    • 1970-01-01
    • 2015-03-15
    • 2018-02-25
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    相关资源
    最近更新 更多