Why are simple for loop expressions restricted to integer ranges?

南笙酒味 提交于 2019-12-01 15:06:30

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).

If you want to keep the for-loop, there's a very simple work-around using the for...in loop with a sequence range operator:

for i in 0I .. 10I do
    printfn "%A" i

The range operator will accept any integer of any size as long as both types match. For example, the following will not compile:

for i in 0 .. 10I do
    printfn "%A" i

Another possible workaround:

[1L..100L] |> List.iter (fun i -> printfn "%i" i)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!