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''
答案 0 :(得分:5)
答案在于类型,但在我解释什么是错的之前,这是使binaryMathFn
函数编译的一种方法:
let binaryMathFn fn stack =
let item1, stack' = pop stack
let item2, stack'' = pop stack'
let result = fn item1 item2
push result stack''
您对Stack
的定义是一个歧视联盟,其中包含一个名为StackContents
的联合案例。当您将函数参数声明为(StackContents stack)
时,您使用的是速记符号:
输入属于Stack
类型,但会立即将该输入与单StackContents
联合案例进行匹配,从输入中有效解包float list
,并指定float list
}到符号stack
。
如果您像我上面建议的那样将参数声明更改为stack
,则F#编译器可以自动推断stack
是Stack
值,因为该函数使用{ {1}}函数,具有此函数签名:
pop
读作一个以Stack -> float * Stack
为输入的函数,并返回Stack
和float
元组作为输出。自{{1使用Stack
调用binaryMathFn
,编译器可以推断pop
必须是stack
值。
答案 1 :(得分:3)
所以问题是:
let binaryMathFn fn (StackContents stack)
应该是
let binaryMathFn fn (stack)
正在发生的是您的定义是提取数据。通常,使用您在函数定义中使用的这种模式匹配是单一的。