E. Peracchia
E. Peracchia

Reputation: 113

F# function calling isn't working properly

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

Answers (1)

Szer
Szer

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

Related Questions