考虑一下
Pentagonal numbers are generated by the formula, Pn=n(3n?1)/2.
Run Code Online (Sandbox Code Playgroud)
我选择在 F# 中创建一个五边形数字序列:
let pentagonalSeq = { 1..Int32.MaxValue } |> Seq.map (fun n -> n*(3*n-1)/2)
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。大多数情况下,我只想计算几个小的整数五边形数。但有时我可能希望得到所有的Int32五边形数字。我在想有可能继续计算它们,直到我最终得到一个OverflowException(我使用的是检查算术)。问题是 F# 对我的想法并不特别满意,大喊大叫
'try/with' cannot be used inside sequence expressions
Run Code Online (Sandbox Code Playgroud)
让这位年轻女士满意的最佳方法是什么?
假设我想创建一个int32_pentagonalSeq:
pentagonalSeq谢谢
我认为吉恩的答案可能是正确的选择!但是,如果您想使用序列表达式来迭代已有序列的元素,您可以编写如下内容:
let takeWhileNonException (input:seq<_>) = seq {
use ps = input.GetEnumerator()
while (try ps.MoveNext() with _ -> false) do
yield ps.Current }
Run Code Online (Sandbox Code Playgroud)
遗憾的是,您不能只用 .. 包装for循环或yield!语句try,with因为(正如您所说),序列表达式不支持异常处理程序。但是,您可以使用底层迭代器并将调用MoveNext包装在异常处理程序中(因为这是一个普通表达式),并false在操作第一次失败时返回。
因此,要获取序列的最后一个数字,您现在可以编写:
pentagonalSeq
|> takeWhileNonException
|> Seq.last
Run Code Online (Sandbox Code Playgroud)