F#的新手,想知道为什么我在定义binaryMathFn时遇到编译时错误.
我还将就改变这个问题的标题提出建议.这不是最具描述性的:)
type Stack = StackContents of float list
let push item (StackContents stack) =
match stack with
| [] -> StackContents [item]
| _ -> StackContents (item::stack)
let pop (StackContents stack) =
match stack with
| [] -> failwith "Stack is empty, nothing to pop!"
| h::t -> (h, StackContents t)
let binaryMathFn fn (StackContents stack) = // Expression type is expected to be of type Stack?
let item1, stack' = pop stack
let item2, stack'' = pop stack'
let result = fn item1 item2
push result stack''
Run Code Online (Sandbox Code Playgroud)
答案是在类型中,但在我解释什么是错误之前,这是使binaryMathFn函数编译的一种方法:
let binaryMathFn fn stack =
let item1, stack' = pop stack
let item2, stack'' = pop stack'
let result = fn item1 item2
push result stack''
Run Code Online (Sandbox Code Playgroud)
你的定义Stack是一个被歧视的联盟,有一个叫做的联合案例StackContents.当您将函数参数声明为时(StackContents stack),您使用的是速记符号,表示:
输入属于类型Stack,但会立即将该输入与单个StackContents联合情况匹配,float list从输入中有效地解压缩,并将其分配float list给符号stack.
如果您像我上面建议的那样,将参数声明更改为简单stack,F#编译器可以自动推断它stack是一个Stack值,因为该函数使用了pop具有此函数签名的函数:
Stack -> float * Stack
Run Code Online (Sandbox Code Playgroud)
这被读作采用一个函数Stack作为输入,并返回的元组float和Stack作为输出.由于binaryMathFn电话pop与stack,编译器可以推断stack必须是一个Stack值.