我刚开始学习F#,我尝试为e生成和评估泰勒级数的前10项。我最初编写了这段代码来计算它:
let fact n = function
| 0 -> 1
| _ -> [1 .. n] |> List.reduce (*)
let taylor e =
let term n = (e ** n) / (fact n)
[1 .. 10]
|> List.map (term)
|> List.reduce (+)这将导致错误,因为**运算符不适用于int。显然,我需要将所有内容转换为float,以便一切都能正常工作。所以:
let fact (n: float) = function
| 0.0 -> 1.0
| _ -> [1.0 .. n] |> List.reduce (*)
let taylor (e: float) =
let term (n: float) = (e ** n) / (fact n)
[1.0 .. 10.0]
|> List.map (term)
|> List.reduce (+)这将产生编译器错误:
EvaluatingEtotheX.fs(9,39): error FS0001: The type 'float -> float' does not match the type
'float'
EvaluatingEtotheX.fs(9,36): error FS0043: The type 'float -> float' does not match the type
'float'(第9行是let term n = (e ** n) / (fact n)的位置)。
为什么这不管用?这个错误到底意味着什么?为什么编译器关心我传递一个函数,这个函数产生的是float而不是一个实际的float值?请注意,我刚刚开始学习F#,所以我不太了解为什么在这种情况下这是行不通的。
发布于 2017-02-17 01:09:44
您正在混合两种类型的语法来定义fact函数。
当使用function关键字时,它隐式地添加一个参数,然后在定义的分支中使用该参数。如果您检查fact定义的签名,您将看到float -> float -> float而不是float -> float。定义中的第一个浮点对应于n,第二个浮点数是通过使用function关键字添加的。
您可以使用function关键字。
let fact = function
| 0.0 -> 1.0
| n -> [1.0 .. n] |> List.reduce (*)或显式匹配表达式(编译器将能够推断n的类型为float,无需手动指定)
let fact n =
match n with
| 0.0 -> 1.0
| _ -> [1.0 .. n] |> List.reduce (*)附带说明,尽管在这种情况下这不是一个实际的问题,但是由于浮点数的二进制表示,将浮点数与精确值进行比较通常不是一个好主意。在您的情况下,保持对整数的fact操作,然后转换结果可能是有意义的:
let term n = (e ** n) / (float (fact (int n))) // assumes fact : int -> inthttps://stackoverflow.com/questions/42287515
复制相似问题