Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write a for loop that increments the index twice

Tags:

f#

In F# the documentation provides two standard for loops. The for to expression is the loop which provides an index, incremented or decremented per item, depending on whether it is a for to or for downto expression.

I want to loop over an array and increment a variable amount of times; specifically twice. in C# this is very straight forward:

for(int i = 0; i < somelength; i += 2) { ... }

How would I achieve the same thing in F#?

like image 777
dcdgo Avatar asked Oct 20 '25 03:10

dcdgo


2 Answers

You can specify the step using the following syntax:

for x in 0 .. 2 .. somelength do 
  printfn "%d" x

For more information, see the documentation for the for .. in expression. More generally, you can also use this for iterating over any sequence (IEnumerable), so this behaves more like C# foreach.

like image 51
Tomas Petricek Avatar answered Oct 21 '25 23:10

Tomas Petricek


Tomas answer is correct and elegant it is worth considering that a in F# loop with an increment of 2 is slower than a loop with increment of 1.

Faster loops in F#:

let print x = printfn "%A" x

// Only increment by +1/-1 allowed for ints    
let case0 () = for x = 0 to 10 do print x
let case1 () = for x = 10 downto 0 do print x
// Special handling in F# compiler ensures these are fast
let case2 () = for x in 0..10 do print x
let case3 (vs : int array) = for x in vs do print x
let case4 (vs : int list) = for x in vs do print x
let case5 (vs : string) = for x in vs do print x

Slower loops in F#:

let print x = printfn "%A" x

// Not int32s
let case0 () = for x in 0L..10L do print x
let case1 () = for x in 0s..10s do print x
let case2 () = for x in 0.0..10.0 do print x
// Not implicit +1/-1 increment
let case3 () = for x in 0..1..10 do print x
let case4 () = for x in 10..-1..0 do print x
let case5 () = for x in 0..2..10 do print x
let case6 () = for x in 10..-2..0 do print x
// Falls back on seq for all cases except arrays, lists and strings
let case7 (vs : int seq) = for x in vs do print x
let case8 (vs : int ResizeArray) = for x in vs do print x
// Very close to fast case 2 but creates an unnecessary list
let case9 () = for x in [0..10] do print x

When F# compiler don't have special handling to ensure quick iteration it falls back on generic code that looks a bit like this:

use e = (Operators.OperatorIntrinsics.RangeInt32 0 2 10).GetEnumerator()
while enumerator.MoveNext() do
  print enumerator.Current

This might or might not be a problem to you but it's worth knowing about I think.

IMHO tail recursion is the way to loop as for and while has a kind of imperative taste to them and thanks to tail call optimization in F# tail recursion is fast if written correctly.

let rec loop i =
  if i < someLength then
    doSomething i
    loop (i + 2)
loop 0
like image 31
Just another metaprogrammer Avatar answered Oct 22 '25 00:10

Just another metaprogrammer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!