简体   繁体   English

F#值不是函数错误

[英]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 . 我注意到您将cdfp模式匹配。 The new value p will shadow parameter p of this.InverseCDF ; 新的值pthis.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. 实际上,您将cdfcdf本身进行了比较,并且when警卫始终为false when比较了cdf ,这是您根本不需要的。

A few corrections: 一些更正:

  1. Remove cdf from pattern matching since you only want to compare its value with p , not match with specific literals. cdf从模式匹配中删除,因为您只想将其值与p进行比较,而不希望与特定文字进行匹配。
  2. Move two 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. 在这种情况下,编译器会抱怨模式匹配不完整。
  3. Use suffix 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM