为什么简单的循环表达式被限制在整数范围内? [英] Why are simple for loop expressions restricted to integer ranges?

查看:186
本文介绍了为什么简单的循环表达式被限制在整数范围内?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据F#规范(参见§6.5.7),简单循环以整数( int aka int32 aka System.Int32 )限制 start stop ,例如

  for i = start to stop do 
// do sth。

我想知道为什么这种for循环的迭代界限必须是 INT32 。为什么不允许 uint32 的int64 bigint



我知道序列迭代表达式( for ... in ... )可以遍历任意序列;但是需要分配一个迭代器,并调用 MoveNext Current 循环可以是(增量计数器,比较,条件跳转)。为了避免这种情况,你坚持使用和一个手动增加循环计数器...



奇怪的是,如果表达式的被包装在一个中,F#不允许< - c $ c> int32 序列表达式,例如:

  seq {for i = 0I to 10I do 
printfn%Ai} $ b所以,我想问题是:是否有一个特殊的原因,只允许 int32 $ b $ / pre

$
for循环?为什么这个限制不适用于包含在 seq 表达式中的循环


<解决方案我不知道为什么F#不允许 int64 范围。这听起来像一个有用的功能...(但我可以理解, int 是C#中的标准类型,也许F#试图遵循这种模式)。 >

至于变通方法,值得添加的是,您还可以编写 inline 高阶函数:

  let inline longFor low high f = 
let rec loop n =
if n <高于f n;循环(n + 1L)
循环低

...然后您可以表达 for int64 范围内以相当简洁的方式循环:

 longFor 1L 100L(fun n  - > 
< whatever>)

我做了一些实验,似乎F#编译器能够相当体面地优化它(lambda函数内联,尾递归 loop 函数变成,而循环)。我不认为这是有保证的,所以你可能需要在高性能的代码中手工检查这个,但是对于简单的例子来说,它似乎工作得很好。



只有一个缺点 - 你将不能使用局部可变变量( let mutable ),因为这些变量不能被lambda函数捕获。所以可能会有额外的成本,间接 ref 单元格(但我不知道这是多大的问题)。

According to the F# spec (see §6.5.7), simple for loops are bounded by integer (int aka int32 aka System.Int32) limits start and stop, e.g.

for i = start to stop do
    // do sth.

I wonder why the iteration bounds for this type of for loop are required to be int32. Why not allow uint32? int64? bigint?

I'm aware that sequence iteration expressions (for ... in ...) can iterate over arbitrary sequences; that however requires allocating an iterator and calling MoveNext and Current and what not and can thus be considerably less efficient than a plain loop could be (increment counter, compare, conditonal jump). To avoid that, you are stuck with using while and a manually incrementing loop counters...

Strangely enough, F# does allow non-int32 loop bounds, if the for expression is wrapped in a sequence expression, e.g.

seq { for i = 0I to 10I do
        printfn "%A" i }

So, I guess the question is: Is there a particular reason for only allowing int32 for loops? And why does this restriction not apply to for loops wrapped in seq expressions?

解决方案

I'm not sure why F# does not allow int64 ranges. It sounds like a useful feature... (but I can understand that int is the standard type for this in C# and perhaps F# tries to follow this pattern).

As for the workarounds, it is worth adding that you can also write inline higher-order function:

let inline longFor low high f = 
  let rec loop n =
    if n < high then f n; loop (n + 1L)
  loop low

...and then you can express for loops over int64 ranges in a fairly succinct way:

longFor 1L 100L (fun n -> 
  <whatever> )

I did a couple of experiments and it seems that the F# compiler is able to optimize this fairly decently (the lambda function is inlined and the tail-recursive loop function is turned into a while loop). I do not think this is guaranteed so you may need to check this by hand in high-performance code, but it seems to work fine for simpler examples.

There is only one disadvantage - you won't be able to use local mutable variables (let mutable) because these cannot be captured by a lambda function. So there may be additional cost with indirect ref cells (but I'm not sure how big problem this is).

这篇关于为什么简单的循环表达式被限制在整数范围内?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆