[英]F# value is not a function error
Continuing my F# learning today by attempting to recreate a simple bisection method using recursion, here I am using the MathNet library to inherit from the Beta distribution. 通过尝试使用递归重新创建简单的二等分方法,继续今天的F#学习,这里我使用MathNet库从Beta发行版继承。
I receive errors on the function 'search' (binary search method) saying the value is not a function and cannot be applied
. 我在函数“搜索”(二进制搜索方法)上收到错误,说
the value is not a function and cannot be applied
。
//Beta class inheriting from MathNet Beta distribution
//Extends the class by implementing an InverseCDF function
type newBeta(alpha:double, beta:double) =
inherit MathNet.Numerics.Distributions.Beta(alpha, beta)
member this.InverseCDF(p: float) =
let rec search (min: float, max: float, acc: uint32) =
let x = (min + max) / 2.0
let error = 0.001
let maxiters : uint32 = 1000u
let cdf = this.CumulativeDistribution(x)
match cdf, (Math.Abs(cdf - p) < error || acc > maxiters) with //while statement
| _ , true -> cdf //auto match cdf and if while statement evaluates true then break and return cdf result
| p , _ -> cdf //if exactly matches p then break and return cdf result
| p , false when p > cdf -> search (min) (x) (acc + 1) //if p > cdf then set max = x and increment then call func with new params
| p , false when p < cdf -> search (x) (max) (acc + 1) //if p < cdf then set min = x and increment then call func with new params
search (0.0) (1.0) (0) //Call the bisection method with initial parameters
Can anyone help? 有人可以帮忙吗? Also obviously any input on how to make this more 'functional' would be cool.
同样很明显,关于如何使它更具“功能性”的任何输入都是很酷的。 Havn't been able to run this yet to test due to the error though.
由于错误,Hav尚无法运行此程序进行测试。 My first 2 match patterns look suspect given I'm trying to return the current value of
cdf
. 考虑到我要返回
cdf
的当前值,我的前两个匹配模式看起来很可疑。
As @John said, your fundamental error is that you declared the function in the tuple form but used it in the curried form. 正如@John所说,您的基本错误是您以元组形式声明了该函数,但以咖喱形式使用了该函数。
I notice that you pattern-matched cdf
with p
. 我注意到您将
cdf
与p
模式匹配。 The new value p
will shadow parameter p
of this.InverseCDF
; 新的值
p
将this.InverseCDF
参数p
; therefore, that parameter isn't available for comparison anymore. 因此,该参数不再可用于比较。 You actually compared
cdf
with cdf
itself and two when
guards are always false
, which you do not want at all. 实际上,您将
cdf
与cdf
本身进行了比较,并且when
警卫始终为false
when
比较了cdf
,这是您根本不需要的。
A few corrections: 一些更正:
cdf
from pattern matching since you only want to compare its value with p
, not match with specific literals. cdf
从模式匹配中删除,因为您只想将其值与p
进行比较,而不希望与特定文字进行匹配。 when
guards up. when
警卫了。 The last pattern shouldn't be a when
guard; when
守卫。 the compiler will complain about incomplete pattern matching in that case. u
for any arithmetic operation on acc
(which is of type unint32
). u
可以对acc
(类型为unint32
)进行任何算术运算。 The new search
function: 新的
search
功能:
let rec search (min: float) (max: float) (acc: uint32) =
let x = (min + max) / 2.0
let error = 0.001
let maxiters : uint32 = 1000u
let cdf = this.CumulativeDistribution(x)
match abs(cdf - p) < error || acc > maxiters with // while statement
| false when p > cdf -> search min x (acc + 1u) // if p > cdf then set max = x and increment then call func with new params
| false when p < cdf -> search x max (acc + 1u) // if p < cdf then set min = x and increment then call func with new params
| _ -> cdf // if exactly matches p or returns true then break and return cdf result
search 0.0 1.0 0u // call the bisection method with initial parameters
Your definition is in tuple style, not curried style - just change it to 您的定义是元组样式,而不是咖喱样式-只需将其更改为
let rec search (min: float) (max: float) (acc: uint32) =
This is because when you call the function you have used the curried style fab
but your definition has the tupled style f (a,b)
这是因为当您调用该函数时,您使用的是curried样式
fab
但您的定义具有元组样式f (a,b)
Also, your match cases aren't quite correct - the last two cases will never be matched because the second case will grab them - you probably want 另外,您的匹配用例不太正确-后两个用例永远不会匹配,因为第二个用例会抓住它们-您可能想要
match cdf, (Math.Abs(cdf - p) < error || acc > maxiters) with //while statement
| _ , true -> cdf //auto match cdf and if while statement evaluates true then break and return cdf result
| p when p=cdf, _ -> cdf //if exactly matches p then break and return cdf result
| p , false when p > cdf -> search (min) (x) (acc + 1) //if p > cdf then set max = x and increment then call func with new params
| p , false when p < cdf -> search (x) (max) (acc + 1) //if p < cdf then set min = x and increment then call func with new params
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.