F#函数调用无法正常工作

时间:2018-03-29 16:21:54

标签: f# stack

我写的F#代码安静问题。 我在F#中做了一个堆栈结构,也做了推送和弹出功能,一切看起来都很好。 我还做了一些指令(ADD,MULT,PUSH,ABS),它们可以处理堆栈中的整数项。 我做了一个函数,作为指令的解释者;它输入一个堆栈和一个指令,输出是堆栈,其中包含指令的结果。当我尝试在解释器中使用push函数时,它不再起作用,它完全忽略了命令。

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)

当我运行它们时会出现问题

let mutable stackProva = Stck[]
stackProva <- exec stackProva (PUSH 5) //not working

当我运行 exec stackProva(PUSH 5)时,我得到的结果是一个空堆栈

stackProva <- stackPush stackProva -3  //working

当我运行 stackPush stackProva -3 时,它实际上将整数-3放入堆栈中。他们正在为我的想法做同样的事情,但在某种程度上它起作用,在另一种方式(我真正想要的那种)它不起作用。 运行这两个命令之后我的期望是 stackProva 包含[-3; 5],但它只包含[-3]。

感谢您提供任何帮助。

1 个答案:

答案 0 :(得分:3)

问题在于您exec的实施。如果它采用空堆栈,则立即返回空堆栈。

这是工作版本:

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"