// postfix evaluation open System // without error handling: printf "Enter Postfix Expression: " let raw_input = System.Console.ReadLine(); let tokens = Array.toList (raw_input.Split()); // get list of tokens let rec eval1(stack,input) = match (stack, input) with | ([x], []) -> x | (a::b::c, "+"::s) -> eval1 ((b+a)::c, s) | (a::b::c, "*"::s) -> eval1 ((b*a)::c, s) | (a::b::c, "-"::s) -> eval1 ((b-a)::c, s) | (a::b::c, "/"::s) -> eval1 ((b/a)::c, s) | (_, x::s) -> eval1 ((int x)::stack, s) | _ -> raise(Exception(sprintf "ERROR, stack=%A, input=%A" stack input));; //printfn "Result = %d" (eval1([],tokens)) let parse_int x = try Ok(int(x)) with | _ -> Error(sprintf "invalid sym %s" x);; // with error handling using the Result monad let rec eval(stack,input) = match (stack, input) with | ([Ok(x)], []) -> Ok(x) | (Ok(a)::Ok(b)::c, "+"::s) -> eval (Ok(b+a)::c, s) | (Ok(a)::Ok(b)::c, "-"::s) -> eval (Ok(b-a)::c, s) | (Ok(a)::Ok(b)::c, "*"::s) -> eval (Ok(b*a)::c, s) | (Ok(0)::Ok(b)::c, "/"::s) -> eval (Error("div by 0")::c, s) | (Ok(a)::Ok(b)::c, "/"::s) -> eval (Ok(b/a)::c, s) // | (Error(_)::rest, s) -> eval (rest,s) // skip errors | (_, x::s) -> eval ((parse_int x)::stack, s) | (s,i) -> Error(sprintf "stack=%A" s);; let result = eval([],tokens) //open Result; let rmap = Result.map let rbind = Result.bind let ifelse okfun errfun result = match result with | Ok(x) -> okfun x | Error(e) -> errfun e result |> ifelse (fun x -> printfn "result = %d" x) (fun e -> printfn "failure: %s" e)