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.