F#键入不匹配时,将Infix运算符作为参数发送



我正在学习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;;

但是,我在infix Operator( , - , *,/)上的最后一个函数中遇到了编译器错误,我试图以参数的方式传递:

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,即它采用一个对参数并返回浮点。这是由于applyBin中的应用程序f (first, second)。二进制运算符+-*/都具有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

如果您愿意投资于自定义组成运营商,则可以更简洁地使用ETA降低并表达功能应用程序的逻辑。

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"操作仍然有两个裁定的参数。它们转换为咖喱参数可以促进部分应用程序,并避免需要命名任何堆栈状态。

相关内容

  • 没有找到相关文章

最新更新