Home > database >  Confusing Error from type matching (I think) - Haskell
Confusing Error from type matching (I think) - Haskell

Time:12-21

Getting an error I just can't make sence of

Basically my program is supposed to preform operations on a custom data type 'Config'

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 )
}

I've only tried to implement one of the instructions 'LOADI' but no matter what I seem to change I get the error:

    • 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 is just a list of Int's but I have to implement it this way

What is (c1, b0, c0) and why doesn't my third value of the config tuple work the same as the others?

Any help would be much appreciated!

Joe

CodePudding user response:

iexec :: Instr -> Config -> Config

Ok, so iexec takes two arguments and returns a Config (a tuple).

iexec (LOADI n) c = do 

Oh, but this says iexec takes two arguments and returns something in the form Monad m => m a (usually IO for beginners but not always).

You don't want do notation here - you're not making a monadic operation at all, just a pure non-monadic computation. For this you should use let ... in ... if you need intermediate values or just the resulting expression if not:

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

Or consider the equivalent:

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

No of course that newStack value being x isn't going to work at all because a Stack is not an Int, but that's just matching your original code.

  • Related