Reputation: 113
I'm having a problem with a piece of code in F# that I wrote. I made a stack structure in F#, also made push and pop function, and all seems working fine. I also made some instruction (ADD, MULT, PUSH, ABS) that work with integer items inside the stack.
I made a function which serves as interpreter for the instructions; it gets in input a stack and an instruction, and the output is the stack with the result of the instruction in it. When I try to use push function inside the interpreter, it dosen't work any more, it completely ignores the command.
type stack =
| Stck of int list
type instr =
| ADD
| MULT
| PUSH of int
| ABS
let stackPush stck num =
match stck with
| Stck(someList) ->
match someList with
| [] -> Stck[num]
| _ -> Stck(num::someList)
let stackPop stck =
match stck with
| Stck(someList) ->
match someList with
| [] -> Stck[]
| _::xEnd -> Stck(xEnd)
let getFirstItem stck =
match stck with
| Stck(someList) ->
match someList with
| [] -> 0
| [xOnly] -> xOnly
| xStart::_ -> xStart
let exec stck instr =
match stck with
| Stck(someList) ->
match someList with
| [] -> Stck[]
| [xOnly] -> Stck[xOnly]
| xStart::xMid::xEnd ->
let tempStack = stackPop(stackPop(stck))
match instr with
| ADD ->
match tempStack with
| _ -> Stck((xStart + xMid)::xEnd)
| MULT ->
match tempStack with
| _ -> Stck((xStart * xMid)::xEnd)
| PUSH x -> stackPush stck x
| ABS -> Stck(abs( xStart)::xEnd)
The problems comes when I run them
let mutable stackProva = Stck[]
stackProva <- exec stackProva (PUSH 5) //not working
When I run the exec stackProva (PUSH 5) , the result I get is an empty stack
stackProva <- stackPush stackProva -3 //working
When I run stackPush stackProva -3 , it actually put the integer -3 inside the stack. They are doing the same stuff for what I think, but in one way it works, in the other (the one I really want) it is not working.
What I expect after running both these command I having stackProva containing [-3;5], but it just contains [-3].
Thanks for any help you could give me.
Upvotes: 3
Views: 80
Reputation: 3476
The problem lies in your implementation of exec
. In case it takes empty stack it returns immediately with empty stack.
Here is working version:
type Stack = Stack of int list
type Instruction =
| ADD
| MULT
| ABS
| PUSH of int
let push num (Stack stack) = Stack (num::stack)
let pop (Stack stack) =
match stack with
| [] -> []
| _::tail -> tail
let tryGetFirstItem (Stack stack) = List.tryHead stack
let exec instr (Stack stack) =
match stack, instr with
| s1::s2::tail, ADD -> Stack (s1+s2::tail)
| s1::s2::tail, MULT -> Stack (s1*s2::tail)
| s1::tail, ABS -> Stack (abs(s1)::tail)
| _, PUSH x -> push x (Stack stack)
| x, _ -> Stack x
Stack []
|> exec (PUSH 1)
|> exec (PUSH 2)
|> exec ADD
|> tryGetFirstItem
|> printfn "%A" //prints "Some 3"
Upvotes: 3