I'm learning F# and is doing an exercise that requires me to perform math operations on a stack of floats.
exception InterpreterError;;
type Instruction =
| ADD
| SUB
| MULT
| DIV
| SIN
| COS
| LOG
| EXP
| PUSH of float;;
type Stack = S of float list;;
let pop (S(s)) =
match s with
| [] -> raise InterpreterError
| x::_ -> (x,S(s));;
let push x (S(s)) : Stack = S(x::s)
let applyBin f s : Stack =
let (first, sGen1) = pop s
let (second,sGen2) = pop sGen1
push (f(first,second)) sGen2;;
let applyUni f s : Stack =
let (first, sGen1) = pop s
push (f(first)) sGen1;;
let intpInstr i s =
match i with
| ADD -> applyBin (+) s
| SUB -> applyBin (-) s
| MULT -> applyBin (*) s
| DIV -> applyBin (/) s
| SIN -> applyUni sin s
| COS -> applyUni cos s
| LOG -> applyUni log s
| EXP -> applyUni exp s
| PUSH(r) -> push r s;;
However, I'm getting a compiler error in the last function intpInstr on the infix operators (+, -, *, /) that I try to pass as arguments:
Type mismatch. Expecting a
float * float -> float
but given a
float * float -> 'a -> 'b
The type 'float' does not match the type ''a -> 'b'
Why does the operators become (+) : float -> float -> 'a -> 'b? I haven't been able to replicate this type in the interactive console. All help appreciated.
With your definition of applyBin
the parameter f
has type (float * float) -> float
i.e. it takes a single pair parameter and returns a float. This is due to the application f (first, second)
in applyBin
. The binary operators +
, -
, *
and /
all have type float -> float -> float
so it looks like you intend that to be the type of f
within applyBin
. You can do this by removing the pair construction:
let applyBin f s : Stack =
let (first, sGen1) = pop s
let (second,sGen2) = pop sGen1
push (f first second) sGen2