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.
Related
For example; the following line
|> Seq.filter(fun i -> i < 123)
is the same thing as
|> Seq.filter((<) 123)
Is there such a thing for the modulo operator? I'm not sure what the 2nd variant is, and can't find it referenced in the documentation either, so it makes searching somewhat difficult. So for bonus points, please tell me what this operator is called! :)
Currently using:
|> Seq.filter (fun i -> i % 2 = 0)
Looking for something like:
|> Seq.filter ((%) 2 = 0)
Your first example is incorrect in saying that fun i -> i < 123 is equal to ((<) 123). That is actually equivalent to fun i -> 123 < i. Let me explain, every operator is just a function but infix rather than prefix. As an example
let (+) x y = x + y
let add x y = x + y
let (-) a b = a - b // notice that the first argument (a) is on the left side of the operator
let subs a b = a - b
knowing this, we can then reason about % and < the same way
let (%) x y = x % y
let (<) x y = x < y
// therefore
fun i -> i < 123
// is equivalent to
fun i -> (<) i 123
// and mathematically equiv to
((>=) 123)
// same with %
fun i -> i % 2
// is equiv to
fun i -> (%) i 2
// thus cant be reduced to eliminate the lambda
Another alternative, if you're dead-set on not writing out the lambda, is to lift it into a function:
let inline isEven x = x % 2 = 0
...
|> Seq.filter isEven
Alas, you are out of luck, because for partial application to be suitable, you need to swap both arguments of the mod operator. The lambda function is way more concise when taking into account that you are applying two operators, which requires function composition.
let flip f a b = f b a
{0..9}
|> Seq.filter ((flip (%) 2) >> ((=) 0))
|> (Seq.map string >> String.concat ", ")
// val it : string = "0, 2, 4, 6, 8"
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|]
The output from below is 15,9,9 however I want 15,9,21
I want to preserve a lazy version so I can put in a new function version in a composed function.
open System
let mutable add2 = fun x-> x+2
let mutable mult3 = fun x-> x*3
let mutable co = add2 >> mult3
let mutable com = lazy( add2 >> mult3)
let mutable com2 = com
add2<- fun x-> x
co 3|> printfn "%A"
com.Force() 3|> printfn "%A"
add2<- fun x-> x+4
com2.Force() 3|> printfn "%A"
I don't think you need lazy values here - lazy value is evaluated once when needed, but its value does not change afterwards. In your case, you need Force to re-evaluate the value in case some dependencies have changed. You can define something like this:
type Delayed<'T> =
| Delayed of (unit -> 'T)
member x.Force() = let (Delayed f) = x in f()
let delay f = Delayed f
This represents a delayed value (really, just a function) with Force method that will evaluate it each time it is accessed. If you rewrite your code using delay, it behaves as you wanted:
let mutable add2 = fun x-> x+2
let mutable mult3 = fun x-> x*3
let mutable com = delay(fun () -> add2 >> mult3)
let mutable com2 = com
add2 <- fun x -> x
com.Force() 3 |> printfn "%A"
add2 <- fun x -> x + 4
com2.Force() 3 |> printfn "%A"
Unlike lazy, this does not do any caching, so calling Force twice will just do the whole thing twice. You could add some caching by tracking a dependency graph of the computation, but it gets more complicated.
In F# I can define an add1 function
let add1 x = x + 1
I can then define an add2 as the add1 function called on itself
let add2 x = add1 (add1 x)
Or by composing the add1 function with itself
let add2 = add1 >> add1
I was trying to implement the lambda calculus combinators in F#, the first being Identity
let I x = x
I then tried to define the Identity of Identity
let II = I >> I
But this caused the following compilation error:
Value restriction. The value 'II' has been inferred to have generic
type
val II : ('_a -> '_a) Either make the arguments to 'II' explicit or, if you do not intend for it to be generic, add a type
annotation
I can however define it as
let II x = I (I x)
I'm new to F# and am curious why?
This error has nothing to do with function composition itself, it's about Value Restriction. It happens because F# compiler infers types as generic as possible, but although it can easily generalize function, it can't generalize value (even though your value is in fact a function).
This answer can help you avoid this problems, but basically you should specify an input parameter:
let II x = (I>>I) x
or
let II x = I >> I <| x
#kagetogi is right.
The F# compiler wants to resolve values into concrete types and it will try to do so as soon as you use the function the first time. So this fails:
let I x = x
let II = I >> I
But this works:
let I x = x
let II = I >> I
II 5 |> printfn "%A"
Here II has type int->int. Which means that the following fails:
let I x = x
let II = I >> I
II 5 |> printfn "%A"
II 5.0 |> printfn "%A"
Because the second call is expecting an int not a float.
That is why in F# the pipe |> operator is preferred over the composition operator >>.
let I x = x
let II x = x |> I |> I
let II' x = x |> (I >> I)
Now finally II has generic type 'a->'a.
They both achieve function composition in the end.
Adding the code annotation also works:
let II<'a> : 'a->'a = I >> I
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.