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#?
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.
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
Tomas already answered your syntax question. Another answer suggests using tail recursion instead.
A third approach with a more f-sharpy feel to it would be something like this:
let myArray = [| 1; 2; 3 ; 4 |]
let stepper f step a =
a
|> Array.mapi (fun x i -> if i % step = 0 then Some (f x) else None)
|> Array.choose id
printfn "%A" <| stepper (fun x -> x * 2) 2 myArray
// prints [|2; 6|]
Related
in F#, it's not allowed to have mutable argument with functions. but if I have a function like the following:
let f x =
while x>0 do
printfn "%d" x
x <- x-1;;
when I compile this, I'm getting a compiler error.(not mutable)
How would I fix this function?
For pass-by-value semantics, you can use parameter shadowing.
Here, a shadowed (because it's the same name) mutable value x is declared on the stack.
let f x =
let mutable x = x
while x > 0 do
printfn "%d" x
x <- x - 1
For pass-by-reference semantics, you'll have to use a reference cell, which is a just a fancy way of passing an object which has a mutable field in it. It's similar to ref in C#:
let f x =
while !x > 0 do
printfn "%d" !x
x := !x - 1
Using a reference cell:
let x = (ref 10)
f x
Debug.Assert(!x = 0)
You could rewrite it like this:
let f x = [x.. -1..1] |> List.iter (printfn "%d")
If you want to keep the while loop, you could do this:
let f (x : byref<int>)=
while x>0 do
printfn "%d" x
x <- x-1
let mutable x = 5
f &x
Depends on whether you want the final, mutated value of x to be passed back to the caller of the function or mutate it only locally.
For local-only mutation, just declare another variable, which would be mutable, but initially will have the value of x:
let f x =
let mutable i = x
while i>0 do
printfn "%d" i
i <- i-1
For passing the result back to the caller, you can use a ref-cell:
let f (x: int ref) =
while x.Value>0 do
printfn "%d" x.Value
x := x.Value - 1
Note that now you have to refer to the ref-cell contents via the .Value property (or you can instead use operator !, as in x := !x - 1), and the mutation is now done via :=. Plus, the consumer of such function now has to create a ref-cell before passing it in:
let x = ref 5
f x
printfn "%d" x.Value // prints "0"
Having said that, I must point out that mutation is generally less reliable, more error-prone than pure values. The normal way to write "loops" in pure functional programming is via recursion:
let rec f x =
if x > 0 then
printf "%d" x
f (x-1)
Here, each call to f makes another call to f with the value of x decreased by 1. This will have the same effect as the loop, but now there is no mutation, which means easier debugging and testing.
in F# if I take a function that takes two arguments, for example, mod (%):
13 % 10
// val it : int = 3
which is the same as
(%) 13 10
// val it : int = 3
is there any way to write it in the pipe notation, currying the 13?
Obviously, the “two-argument function” is actually a one-argument function that returns an intermediate function. So can pipe
10 |> (%) 13
// val it : int = 3
However, I need the other way around, i.e. pipe the first argument 13, having the second argument 10 partially applied, but not the first one.
Is there anything in the language that helps to do that, without creating extra lambdas every time, i.e. to avoid the following?
13 |> (fun x -> x % 10)
There is no built-in, standard way to do this. Moreover, due to how function application works, it's impossible to do so: as soon as you write (%) 13, you've already applied the first argument, because function application has the highest and non-configurable precedence in F#.
You can, if course, make yourself a special function to produce a "weird" function application - one that would apply the second argument and leave a hole for the first:
let ap f x = fun y -> f y x
And then:
let x = 13 |> ap (%) 10
> x : int = 3
Incidentally, the function ap is a semi-standard occurrence in ML languages, and is usually called flip, because what it does is "flipping" the order of the arguments:
let flip f x y = f y x
Or, you can even make it into an operator:
let (-*-) = flip
And then:
let x = 13 |> (%) -*- 10
> x : int = 3
However, this sort of trickery gets unreadable very quickly. In practice, it is far more preferable to just declare a function that does what you need:
let mod10 x = x % 10
And then:
let x = 13 |> mod10
Or, if you really need it to be very general:
let mod' x y = y % x
And then:
let x = 13 |> mod' 10
You can write a combinator that will do this for any function of two arguments:
let inline flip f y x = f x y
This can be used as:
13 |> flip (%) 10
F# already contains an operator that will do what you want, namely <|:
10 |> (%) <| 13;;
val it : int = 10
This is equivalent to
(10 |> (%)) 13;;
val it : int = 10
K, you are looking for a flip
let flip f a b = f b a
In C, I would solve the problem with a loop. To represent the idea, something like:
void foo(int x){
while(x > 0){
printf("%d", x % 10);
x /= 10;
}
}
With F#, I am unable to make the function return the single values. I tried:
let reverse =
let aux =
fun x ->
x % 10
let rec aux2 =
fun x ->
if x = 0 then 0
else aux2(aux(x / 10))
aux2 n
but it returns always the base case 0.
I cannot get my mind beyond this approach, where the recursion results are maintained with an operation, and cannot be reported (according to may comprehension) individually:
let reverse2 =
let rec aux =
fun x ->
if x = 0 then 0
else (x % 10) + aux (x / 10) // The operation returning the result
aux n
This is a simple exercise I am doing in order to "functionalize" my mind. Hence, I am looking for an approach to this problem not involving library functions.
A for loop that changes the value of mutable variables can be rewritten as a recursive function. You can think of the mutable variables as implicit parameters to the function. So if we have a mutable variable x, we need to instead pass the new state of x explicitly as a function parameter. The closest equivalent to your C function as a recursive F# function is this:
let rec foo x =
if x > 0 then
printf "%d" (x % 10)
foo (x / 10)
This in itself isn't particularly functional because it returns unit and only has side effects. You can collect the result of each loop using another parameter. This is often called an accumulator:
let foo x =
let rec loop x acc =
if x > 0 then
loop (x / 10) (x % 10 :: acc)
else acc
loop x [] |> List.rev
foo 100 // [0; 0; 1]
I made an inner loop function that is actually the recursive one. The outer foo function starts off the inner loop with [] as the accumulator. Items are added to the start of the list during each iteration and the accumulator list is reversed at the end.
You can use another type as the accumulator, e.g. a string, and append to the string instead of adding items to the list.
I've recently started learning F#. I'm attempting to loop through a list of functions, applying each function to a value. For example, I have:
let identity x = fun x -> x
let square x = fun x -> x * x
let cube x = fun x -> x * x * x
let functions = [identity; square; cube]
I would now like to do something like the following:
let resultList = List.map(fun elem -> elem 3) functions
where the result value would be the list [3;9;27]. However, this is not what happens. Instead, I get:
val resultList : (int -> int) list = [<fun:Invoke#3000>; <fun:Invoke#3000>; <fun:Invoke#3000>]
I guess I'm not entirely convinced that using map is the right way forward any longer, so my questions are:
Why do I not get a list of numbers?
How would return a list of numbers?
What does <fun:Invoke> mean?
Thanks very much for your help.
Daniel
Your functions aren't quite correctly defined, they're taking an extra (unused) argument and are therefore just partially applied and not evaluated as you're expecting. Besides that, your thinking is correct;
let identity2 = fun x -> x
let square2 = fun x -> x * x
let cube2 = fun x -> x * x * x
let functions = [identity2; square2; cube2]
let resultList = List.map(fun elem -> elem 3) functions;;
> val resultList : int list = [3; 9; 27]
Although I'm not an F# expert, the <fun:Invoke> would in this case seem to indicate that the value is a (partially applied) function.
Because I like to simplify where I can, you can reduce a bit on Joachim's answer by removing the fun from your functions:
let identity x = x
let square x = x * x
let cube x = x * x * x
let functions = [identity; square; cube]
printfn "%A" (List.map(fun elem -> elem 3) functions)
Gives the output [3; 9; 27]
For me this is more natural. I didn't understand why the functions themselves needed to wrap funcs, rather than simply be the function.
Creating a Parallel.ForEach expression of this form:
let low = max 1 (k-m)
let high = min (k-1) n
let rangesize = (high+1-low)/(PROCS*3)
Parallel.ForEach(Partitioner.Create(low, high+1, rangesize), (fun j ->
let i = k - j
if x.[i-1] = y.[j-1] then
a.[i] <- b.[i-1] + 1
else
a.[i] <- max c.[i] c.[i-1]
)) |> ignore
Causes me to receive the error: No overloads match for method 'ForEach'. However I am using the Parallel.ForEach<TSource> Method (Partitioner<TSource>, Action<TSource>) and it seems right to me. Am I missing something?
Edited: I am trying to obtain the same results as the code below (that does not use a Partitioner):
let low = max 1 (k-m)
let high = min (k-1) n
let rangesize = (high+1-low)/(PROCS*3)
let A = [| low .. high |]
Parallel.ForEach(A, fun (j:int) ->
let i = k - j
if x.[i-1] = y.[j-1] then
a.[i] <- b.[i-1] + 1
else
a.[i] <- max c.[i] c.[i-1]
) |> ignore
Are you sure that you have opened all necessary namespaces, all the values you are using (low, high and PROCS) are defined and that your code does not accidentally redefine some of the names that you're using (like Partitioner)?
I created a very simple F# script with this code and it seems to be working fine (I refactored the code to create a partitioner called p, but that does not affect the behavior):
open System.Threading.Tasks
open System.Collections.Concurrent
let PROCS = 10
let low, high = 0, 100
let p = Partitioner.Create(low, high+1, high+1-low/(PROCS*3))
Parallel.ForEach(p, (fun j ->
printfn "%A" j // Print the desired range (using %A as it is a tuple)
)) |> ignore
It is important that the value j is actually a pair of type int * int, so if the body uses it in a wrong way (e.g. as an int), you will get the error. In that case, you can add a type annotation to j and you would get a more useful error elsewhere:
Parallel.ForEach(p, (fun (j:int * int) ->
printfn "%d" j // Error here, because `j` is used as an int, but it is a pair!
)) |> ignore
This means that if you want to perform something for all j values in the original range, you need to write something like this:
Parallel.ForEach(p, (fun (loJ, hiJ) ->
for j in loJ .. hiJ - 1 do // Iterate over all js in this partition
printfn "%d" j // process the current j
)) |> ignore
Aside, I guess that the last argument to Partitioner.Create should actually be (high+1-low)/(PROCS*3) - you probably want to divide the total number of steps, not just the low value.