F# 函数匹配

3
有没有一种在F#中定义一个函数的方法,可以计算出到提供的整数参数为止的所有自然数之和,而不使用match结构。
换句话说,为什么以下代码是错误的?
let Sum 0 = 0
let Sum n = n + Sum (n - 1)

1
不是很明白,你为什么想要这样做呢? - John Palmer
2
我只是出于好奇而提问,因为Haskell支持这种语法,我觉得它有点优雅。 - ax1mx2
在那种情况下,不太可能,但如果你非常绝望的话,可能会通过一些可怕的黑客手段实现。 - John Palmer
2个回答

4
如果您想使用递归形式而不使用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 代码中“太显然”的部分。


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

我只是在想为什么以下语句被认为是有效的“let Sum 0 = 0”,但是既没有文档,也没有书籍指出可以对这个结构进行任何操作。 - ax1mx2
1
它实际上不会成为一个无限循环。当x等于Int32.MinValue时,从中减去一个将产生Int32.MaxValue,并最终该值将达到零。 - phoog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接