F#函数匹配
F# Function Matching
在 F# 中有没有一种方法可以定义一个函数,该函数给出所有自然数的总和,直到提供的整数参数,而不使用 match
构造。
也就是说,为什么下面的代码是错误的?
let Sum 0 = 0
let Sum n = n + Sum (n - 1)
以下代码是错误的,因为它包含 Sum
的双重定义。 F# 语法与 Haskell 不同,它需要一个函数条目,内部完成分支,使用 match
或 if
链。
此外,这样的代码不是很准确,因为如果收到负参数,它就会陷入无限循环。
有几种简单的方法可以在没有 match
的情况下完成您需要的操作。请注意,它们还需要参数范围检查:
let Sum1 x = x * (x+1) / 2 // too obvious
let Sum2 x = Seq.init id |> Seq.take (x+1) |> Seq.sum
如果您特别想要递归形式而不使用 match
,只需使用常规条件:
let rec Sum n =
if n = 0 then 0 else n + Sum (n-1)
模仿 Haskell 的惯用方法是:
let rec Sum = function
| 0 -> 0
| n -> n + Sum (n-1)
但是你实际上不需要递归,因为有一个封闭的形式;请参阅@bytebuster 代码的 "too obvious" 部分。
在 F# 中有没有一种方法可以定义一个函数,该函数给出所有自然数的总和,直到提供的整数参数,而不使用 match
构造。
也就是说,为什么下面的代码是错误的?
let Sum 0 = 0
let Sum n = n + Sum (n - 1)
以下代码是错误的,因为它包含 Sum
的双重定义。 F# 语法与 Haskell 不同,它需要一个函数条目,内部完成分支,使用 match
或 if
链。
此外,这样的代码不是很准确,因为如果收到负参数,它就会陷入无限循环。
有几种简单的方法可以在没有 match
的情况下完成您需要的操作。请注意,它们还需要参数范围检查:
let Sum1 x = x * (x+1) / 2 // too obvious
let Sum2 x = Seq.init id |> Seq.take (x+1) |> Seq.sum
如果您特别想要递归形式而不使用 match
,只需使用常规条件:
let rec Sum n =
if n = 0 then 0 else n + Sum (n-1)
模仿 Haskell 的惯用方法是:
let rec Sum = function
| 0 -> 0
| n -> n + Sum (n-1)
但是你实际上不需要递归,因为有一个封闭的形式;请参阅@bytebuster 代码的 "too obvious" 部分。