Function 将中缀运算符作为参数发送时F#类型不匹配

Function 将中缀运算符作为参数发送时F#类型不匹配,function,types,f#,arguments,mismatch,Function,Types,F#,Arguments,Mismatch,我正在学习F#,正在做一个练习,要求我在一堆浮点数上执行数学运算 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 Inter

我正在学习F#,正在做一个练习,要求我在一堆浮点数上执行数学运算

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;;
但是,我在尝试作为参数传递的中缀运算符(+、-、*、/)上的最后一个函数intpInstr中遇到编译器错误:

Type mismatch. Expecting a
    float * float -> float    
but given a
    float * float -> 'a -> 'b    
The type 'float' does not match the type ''a -> 'b'
为什么操作符变成(+):float->float->a->b?我无法在交互控制台中复制这种类型。
感谢所有帮助。

根据您对
applyBin
的定义,参数
f
的类型为
(float*float)->float
,即它接受一对参数并返回一个float。这是由于
applyBin
中的应用程序
f(第一、第二)
。二进制运算符
+
-
*
/
都有类型
float->float->float
,因此看起来您希望它是
applyBin
中的
f
类型。可以通过删除对结构来执行此操作:

let applyBin f s : Stack = 
    let (first, sGen1) = pop s
    let (second,sGen2) = pop sGen1
    push (f first second) sGen2

如果您愿意投资定制复合运算符,那么可以更简洁地使用和表达函数应用程序的逻辑

let (>|>) f g = f >> fun (b, c) -> g b c
let applyUna f = 
    pop >|> fun first ->
    push (f first)
let applyBin f = 
    pop >|> fun first -> 
    pop >|> fun second ->
    push (f first second) 

“pop”操作仍返回两个元组参数。将它们转换为curried参数可以实现部分应用,并且避免了命名任何堆栈状态的需要。

这似乎起到了作用。谢谢我只是假设它需要一个元组,因为这就是我被告知实现中缀运算符的方式。