F-升号 (F#) 无类型无穷大
我想知道为什么 F-Sharp 不支持无穷大。
这在 Ruby 中可以工作(但在 f# 中不行):
let numbers n = [1 .. 1/0] |> Seq.take(n)
-> System.DivideByZeroException:尝试除以零。
我可以用更复杂的方式编写相同的功能:
let numbers n = 1 |> Seq.unfold (fun i -> Some (i, i + 1)) |> Seq.take(n)
->有效
但是我认为第一个会更清楚。 我找不到任何在 F# 中使用动态类型无穷大的简单方法。 有 infinity 关键字,但它是 float:
let a = Math.bigint +infinity;;
System.OverflowException:BigInteger 无法表示无穷大。 在 System.Numerics.BigInteger..ctor(双值) 在.$FSI_0045.main@() 由于错误而停止
编辑:这似乎也可以在迭代中工作:
let numbers n = Seq.initInfinite (fun i -> i+1) |> Seq.take(n)
I wonder why F-Sharp doesn't support infinity.
This would work in Ruby (but not in f#):
let numbers n = [1 .. 1/0] |> Seq.take(n)
-> System.DivideByZeroException: Attempted to divide by zero.
I can write the same functionality in much complex way:
let numbers n = 1 |> Seq.unfold (fun i -> Some (i, i + 1)) |> Seq.take(n)
-> works
However I think that first one would be much more clear.
I can't find any easy way to use dynamically typed infinity in F#.
There is infinity keyword but it is float:
let a = Math.bigint +infinity;;
System.OverflowException: BigInteger cannot represent infinity.
at System.Numerics.BigInteger..ctor(Double value)
at .$FSI_0045.main@()
stopped due to error
Edit: also this seems to work in iteration:
let numbers n = Seq.initInfinite (fun i -> i+1) |> Seq.take(n)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,F# 列表不是惰性的(我不确定 Ruby 列表是惰性的),因此即使使用无穷大的一般概念,您的第一个示例也永远无法工作。
其次,Int32 中没有无穷大值。只有最大值。不过 Double 中存在正无穷大和负无穷大。
把它们放在一起,这是可行的:
但我觉得 Seq.initInfinite 是你最好的选择。上面的代码对我来说看起来很奇怪。 (或者至少使用 Double.PositiveInfinity 而不是 1./0。)
乍一看,该语言中的一个不错的选择是像 haskell 中那样的无限范围运算符: seq { 1.. } 问题是它会只适用于 seq,所以我想仅仅为了这个功能,支持后缀运算符的额外工作是不值得的。
底线:在我看来,使用 Seq.initInfinite。
First of all, F# lists are not lazy, (I'm not sure Ruby lists are lazy), so even with a general notion of infinity your first example can never work.
Second, there is no infinity value in Int32. Only MaxValue. There is a positive and negative infinity in Double though.
Putting it together, this works:
I feel however Seq.initInfinite is your best option. The code above looks strange to me. (Or at least use Double.PositiveInfinity instead of 1./0.)
At first sight, a nice option to have in the language would be an infinite range operator like in haskell: seq { 1.. } The problem is that it would only work for seq, so I guess the extra work to support postfix operators is not worth it for this feature alone.
Bottom line: in my opinion, use Seq.initInfinite.
我认为以下是 F# 中无限范围的最佳解决方案;通过标记函数
内联
,我们比“动态类型无限”做得更好,我们得到结构类型无限范围(适用于int32,int64,bigint,...任何具有静态成员的类型+
它接受两个自己类型的参数并返回一个自己类型的值):I think the following is the best solution to infinite ranges in F#; by marking the function
inline
we do better than "dynamically typed infinity" we get structurally typed infinite ranges (works with int32, int64, bigint, ... any type that which has a static member+
which takes two arguments of its own type and returns a value of it's own type):