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
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# 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.
I currently use this function
let inc (i : int ref) =
let res = !i
i := res + 1
res
to write things like
let str = input.[inc index]
How define increment operator ++, so that I could write
let str = input.[index++]
You cannot define postfix operators in F# - see 4.4 Operators and Precedence. If you agree to making it prefix instead, then you can define, for example,
let (++) x = incr x; !x
and use it as below:
let y = ref 1
(++) y;;
val y : int ref = {contents = 2;}
UPDATE: as fpessoa pointed out ++ cannot be used as a genuine prefix operator, indeed (see here and there for the rules upon characters and character sequences comprising valid F# prefix operators).
Interestingly, the unary + can be overloaded for the purpose:
let (~+) x = incr x; !x
allowing
let y = ref 1
+y;;
val y : int ref = {contents = 2;}
Nevertheless, it makes sense to mention that the idea of iterating an array like below
let v = [| 1..5 |]
let i = ref -1
v |> Seq.iter (fun _ -> printfn "%d" v.[+i])
for the sake of "readability" looks at least strange in comparison with the idiomatic functional manner
[|1..5|] |> Seq.iter (printfn "%d")
which some initiated already had expressed in comments to the original question.
I was trying to write it as a prefix operator as suggested, but you can't define (++) as a proper prefix operator, i.e., run things like ++y without the () as you could for example for (!+):
let (!+) (i : int ref) = incr i; !i
let v = [| 1..5 |]
let i = ref -1
[1..5] |> Seq.iter (fun _ -> printfn "%d" v.[!+i])
Sorry, but I guess the answer is that actually you can't do even that.
I suspect that I am missing something very obvious here but this doesn't work:
let t = Array2D.create 1 1 1.0
for x in t do printfn "%f" x;;
It fails with
error FS0001: The type 'obj' is not compatible with any of the types float,float32,decimal, arising from the use of a printf-style format string
Interestingly using printf "%A" or "%O" prints the expected values which suggests to me that the problem is with the type inference
The corresponding code for a 1D array works fine
let t = Array.create 1 1.0
for x in t do printfn "%f" x;;
For reference this is on version 2.0 (both interactive and compiler) running on the latest mono
In .NET, a 1D array implicitly implements IList, which means it also implements (by inheritance) IEnumerable<T>. So, when you run:
let t = Array.create 1 1.0
for x in t do printfn "%f" x;;
the F# compiler emits code which gets an implementation of IEnumerable<T> (seq<T> in F#) from t, then iterates over it. Since it's able to get an IEnumerable<T> from the array, x will have type T.
On the other hand, multi-dimensional arrays (2d, 3d, etc.) only implement IEnumerable (not IEnumerable<T>) so the F# compiler infers the type of x as System.Object (or obj, in F#).
There are two solutions for what you want:
Cast each individual value within the loop, before printing it:
for x in t do printfn "%f" (x :?> float);;
Or, use Seq.cast to create and iterate over a strongly-typed enumerator:
for x in (Seq.cast<float> t) do printfn "%f" x;;
As Jack pointed out, this is a problem. One easy solution is:
let t = Array2D.create 2 2 1.0
t |> Array2D.iter (printfn "%f");;
And if you really like the for .. in .. do syntax:
type Array2DForLoopBuilder() =
member __.Zero() = ()
member __.For(a, f) = Array2D.iter f a
member __.Run e = e
let a2dfor = Array2DForLoopBuilder()
let t = Array2D.init 2 2 (fun a b -> float a + float b)
a2dfor { for x in t do printfn "%f" x }