Maybe it's too simple thing to do, but I can't find any answer in the web
I'm try to Increment value in F# (like count++ in C#).
I don't want to use "mutable" option,
I'm just want to see an example, who Increment function in F# should look like.
And how do I use it.
The idea of "incrementing a value" in the same sense as in C++ only makes sense when you're working with mutable values or when you're using a mutable reference cell (essentially a simple object that stores a mutable value). If you have a mutable reference cell, you can use incr function:
let count = ref 0
incr count
If you use a mutable variable, then there is no built-in function for this and you need to write count + 1:
let mutable count = 0
count <- count + 1
If you're writing code using immutable values, then you will generally just write count + 1 and then pass the result to some function (or somewhere else - this depends on the specific case). For example, to calculate the length of an F# list, you would write:
let rec length list =
match list with
| [] -> 0
| _::tail -> 1 + (length tail)
In this example, the expression 1 + (...) is the code corresponding to i++ in a C++ code that iterates over a list and computes its length. The result of the expression is not assigned to a new variable, because it is returned directly as a result of the length function.
EDIT Parameters of functions are immutable meaning that you cannot change their values. As mentioned by Lee, you can use variable shadowing to hide the old value with a new one - but note that this only has a local effect (it is like defining a new variable with different name to store the new value). For example:
let rec length list count =
match list with
| [] -> count
| _::tail ->
let count = count + 1 // Variable shadowing used here
length tail count
You cannot write a function to simplify the line let count = count + 1 and as mentioned above, this is equivalent to writing let newCount = count + 1 and then using newCount on the last line.
You can't simulate a postincrement operator but you can do preincrement
let inline (+=) (x : byref<_>) y = x <- x + y
let mutable a = 0
&a += 1
or
let inline incv (x : byref<_>) = x <- x + LanguagePrimitives.GenericOne; x
let mutable b = 0
incv &b
If you don't want to use mutable then you can't really do a destructive update like ++ is in C#. You could shadow a variable with a new one with the same name e.g.
let x = 4;
let x = x + 1 in (x+4) //returns 8
although you couldn't write this as a function.
EDIT: If do want to use mutable variables then you can create a function which modifies a ref:
let increment (ir: int ref) = ir := !ir + 1
You can then use it as
let i = ref 1
increment i
let iv = !i //iv contains 2
As Tomas points out in his answer, this function already exists and is called incr.
Related
I have this function that checks the number of occurrences of a pattern in a string. The problem is that is keeps returning 0 no matter the input. The most frustrating part is that it worked 2 min ago and I did not change anything.
let Counter (text : string) (pattern : string) =
let mutable count = 0
let mutable i = 0
while ((i = text.IndexOf(pattern, i)) <> false) do
i <- i + pattern.Length
count <- count + 1
count
The main problem is that it looks like you're trying to assign a new value to i inside the test in the while loop, but the = operator tests equality and does not perform assignment. The <- assignment operator has return type unit (it does not return the assigned value), so the fix can't be as simple as replacing the call to = with a call to <-.
The most straightforward fix is probably to break that test out into a separate inner function:
let counter (text : string) (pattern : string) =
let mutable i = 0
let moveNext() =
i <- text.IndexOf(pattern, i)
i
let mutable count = 0
while (moveNext() >= 0) do
i <- i + pattern.Length
count <- count + 1
count
However, note that this is not idiomatic F# code. Instead, I'd write it like this:
let counter (text : string) (pattern : string) =
let rec countFrom (i:int) total =
match text.IndexOf(pattern, i) with
| j when j >= 0 -> countFrom (j+pattern.Length) (total+1)
| _ -> total
countFrom 0 0
I have been trying to write a program which prints out a factorial without actually using recursion.
Here is the code
let factorial x =
let mutable n = x
while n > 0 do
let result = n*(n-1)
n <- (n-1)
result
The issue is that when I try to run the code it tells me that the expected result is a unit, whereas the input is clearly an integer, which obviously results in an error. However, I have checked all my variables and the compiler interprets them as integers, so what is the issue
There are several issues with your code here, you must keep in mind indentation in f# is very important, for you want to do your code should be:
let factorial x =
let mutable n = x
let mutable result = 1
while n > 0 do
result <- n * (n-1)
n <- (n - 1)
result
You were declaring the result variable inside the while scope and returning it outside it. Your code however is incorrect, I took the liberty of modify it, here what I did:
let factorial x =
let mutable n = x
let mutable result = 1
while n >= 1 do
result <- result * n
n <- (n - 1)
result
Am trying to count down from 6 to 1 in a non-recursive factorial function and getting a compiler error:
let fact x =
let mutable product = 1
for i in x..-1..1 do
product <- product * i
product
// Error on the 6 - type 'int' does not support the operator '..-'
let answer = fact 6
printfn "%i" answer
I got this idea from near the bottom here
Have changed the function to just count up and it works, but I'm interested to know why this failed. Is there a better way to count down?
Using VS2012 update 3
Have changed the function to just count up and it works, but I'm interested to know why this failed.
Your example fails because .. and - are two different operators, the compiler needs separation between those. Instead of wrapping -1 by parentheses, you could add spaces:
let fact x =
let mutable product = 1
for i in x .. -1 .. 1 do
product <- product * i
product
Is there a better way to count down?
The less well-known for .. downto .. do construct is more appropriate to use here.
let fact x =
let mutable product = 1
for i = x downto 1 do
product <- product * i
product
This works:
let fact x =
let mutable product = 1
for i in x..(-1)..1 do
product <- product * i
product
As does this (as used in the link in the question):
let fact x =
let mutable product = 1
for i in x .. -1 .. 1 do
product <- product * i
product
PS: also note that there are more functional ways to compute a factorial (bad to use mutable variables); the most obvious using recursion:
let rec fact x =
if x > 2
then x * (fact (x - 1))
else x
or a one-liner using lists:
let fact x = [2..x] |> List.reduce (*)
Try to use brackets:
...
for i in x..(-1)..1 do
...
IE,
What am I doing wrong here? Does it have to to with lists, sequences and arrays and the way the limitations work?
So here is the setup: I'm trying to generate some primes. I see that there are a billion text files of a billion primes. The question isn't why...the question is how are the guys using python calculating all of the primes below 1,000,000 in milliseconds on this post...and what am I doing wrong with the following F# code?
let sieve_primes2 top_number =
let numbers = [ for i in 2 .. top_number do yield i ]
let sieve (n:int list) =
match n with
| [x] -> x,[]
| hd :: tl -> hd, List.choose(fun x -> if x%hd = 0 then None else Some(x)) tl
| _ -> failwith "Pernicious list error."
let rec sieve_prime (p:int list) (n:int list) =
match (sieve n) with
| i,[] -> i::p
| i,n' -> sieve_prime (i::p) n'
sieve_prime [1;0] numbers
With the timer on in FSI, I get 4.33 seconds worth of CPU for 100000... after that, it all just blows up.
Your sieve function is slow because you tried to filter out composite numbers up to top_number. With Sieve of Eratosthenes, you only need to do so until sqrt(top_number) and remaining numbers are inherently prime. Suppose we havetop_number = 1,000,000, your function does 78498 rounds of filtering (the number of primes until 1,000,000) while the original sieve only does so 168 times (the number of primes until 1,000).
You can avoid generating even numbers except 2 which cannot be prime from the beginning. Moreover, sieve and sieve_prime can be merged into a recursive function. And you could use lightweight List.filter instead of List.choose.
Incorporating above suggestions:
let sieve_primes top_number =
let numbers = [ yield 2
for i in 3..2..top_number -> i ]
let rec sieve ns =
match ns with
| [] -> []
| x::xs when x*x > top_number -> ns
| x::xs -> x::sieve (List.filter(fun y -> y%x <> 0) xs)
sieve numbers
In my machine, the updated version is very fast and it completes within 0.6s for top_number = 1,000,000.
Based on my code here: stackoverflow.com/a/8371684/124259
Gets the first 1 million primes in 22 milliseconds in fsi - a significant part is probably compiling the code at this point.
#time "on"
let limit = 1000000
//returns an array of all the primes up to limit
let table =
let table = Array.create limit true //use bools in the table to save on memory
let tlimit = int (sqrt (float limit)) //max test no for table, ints should be fine
let mutable curfactor = 1;
while curfactor < tlimit-2 do
curfactor <- curfactor+2
if table.[curfactor] then //simple optimisation
let mutable v = curfactor*2
while v < limit do
table.[v] <- false
v <- v + curfactor
let out = Array.create (100000) 0 //this needs to be greater than pi(limit)
let mutable idx = 1
out.[0]<-2
let mutable curx=1
while curx < limit-2 do
curx <- curx + 2
if table.[curx] then
out.[idx]<-curx
idx <- idx+1
out
There have been several good answers both as to general trial division algorithm using lists (#pad) and in choice of an array for a sieving data structure using the Sieve of Eratosthenes (SoE) (#John Palmer and #Jon Harrop). However, #pad's list algorithm isn't particularly fast and will "blow up" for larger sieving ranges and #John Palmer's array solution is somewhat more complex, uses more memory than necessary, and uses external mutable state so is not different than if the program were written in an imperative language such as C#.
EDIT_ADD: I've edited the below code (old code with line comments) modifying the sequence expression to avoid some function calls so as to reflect more of an "iterator style" and while it saved 20% of the speed it still doesn't come close to that of a true C# iterator which is about the same speed as the "roll your own enumerator" final F# code. I've modified the timing information below accordingly. END_EDIT
The following true SoE program only uses 64 KBytes of memory to sieve primes up to a million (due to only considering odd numbers and using the packed bit BitArray) and still is almost as fast as #John Palmer's program at about 40 milliseconds to sieve to one million on a i7 2700K (3.5 GHz), with only a few lines of code:
open System.Collections
let primesSoE top_number=
let BFLMT = int((top_number-3u)/2u) in let buf = BitArray(BFLMT+1,true)
let SQRTLMT = (int(sqrt (double top_number))-3)/2
let rec cullp i p = if i <= BFLMT then (buf.[i] <- false; cullp (i+p) p)
for i = 0 to SQRTLMT do if buf.[i] then let p = i+i+3 in cullp (p*(i+1)+i) p
seq { for i = -1 to BFLMT do if i<0 then yield 2u
elif buf.[i] then yield uint32(3+i+i) }
// seq { yield 2u; yield! seq { 0..BFLMT } |> Seq.filter (fun i->buf.[i])
// |> Seq.map (fun i->uint32 (i+i+3)) }
primesSOE 1000000u |> Seq.length;;
Almost all of the elapsed time is spent in the last two lines enumerating the found primes due to the inefficiency of the sequence run time library as well as the cost of enumerating itself at about 28 clock cycles per function call and return with about 16 function calls per iteration. This could be reduced to only a few function calls per iteration by rolling our own iterator, but the code is not as concise; note that in the following code there is no mutable state exposed other than the contents of the sieving array and the reference variable necessary for the iterator implementation using object expressions:
open System
open System.Collections
open System.Collections.Generic
let primesSoE top_number=
let BFLMT = int((top_number-3u)/2u) in let buf = BitArray(BFLMT+1,true)
let SQRTLMT = (int(sqrt (double top_number))-3)/2
let rec cullp i p = if i <= BFLMT then (buf.[i] <- false; cullp (i+p) p)
for i = 0 to SQRTLMT do if buf.[i] then let p = i+i+3 in cullp (p*(i+1)+i) p
let nmrtr() =
let i = ref -2
let rec nxti() = i:=!i+1;if !i<=BFLMT && not buf.[!i] then nxti() else !i<=BFLMT
let inline curr() = if !i<0 then (if !i= -1 then 2u else failwith "Enumeration not started!!!")
else let v = uint32 !i in v+v+3u
{ new IEnumerator<_> with
member this.Current = curr()
interface IEnumerator with
member this.Current = box (curr())
member this.MoveNext() = if !i< -1 then i:=!i+1;true else nxti()
member this.Reset() = failwith "IEnumerator.Reset() not implemented!!!"
interface IDisposable with
member this.Dispose() = () }
{ new IEnumerable<_> with
member this.GetEnumerator() = nmrtr()
interface IEnumerable with
member this.GetEnumerator() = nmrtr() :> IEnumerator }
primesSOE 1000000u |> Seq.length;;
The above code takes about 8.5 milliseconds to sieve the primes to a million on the same machine due to greatly reducing the number of function calls per iteration to about three from about 16. This is about the same speed as C# code written in the same style. It's too bad that F#'s iterator style as I used in the first example doesn't automatically generate the IEnumerable boiler plate code as C# iterators do, but I guess that is the intention of sequences - just that they are so damned inefficient as to speed performance due to being implemented as sequence computation expressions.
Now, less than half of the time is expended in enumerating the prime results for a much better use of CPU time.
What am I doing wrong here?
You've implemented a different algorithm that goes through each possible value and uses % to determine if it needs to be removed. What you're supposed to be doing is stepping through with a fixed increment removing multiples. That would be asymptotically.
You cannot step through lists efficiently because they don't support random access so use arrays.
The function matching is based on the definition of the file in F#:
let f2 x y = x + y
let value5 = f2 10 20
let value = f2(10, 20) <-- Error
let f3 (x, y) = x + y
let value6 = f3(10, 20)
let value = f3 10 20 <-- Error
However, I can use in both ways with one parameter with F#:
let f n = n + 10
let value3 = f 10
let value4 = f(10)
Why is this? Does F# treat parameter matching differently when there is only one input parameter?
As ashays correctly explains, the two ways of declaring functions are different. You can see that by looking at the type signature. Here is an F# interactive session:
> let f1 (x, y) = x + y;;
val f1 : int * int -> int
> let f2 x y = x + y;;
val f2 : int -> int -> int
The first function takes a tuple of type int * int and returns int. When calling it, you need to specify the tuple (which is just a single value):
// Using tuple directly as the argument
f1 (1, 2)
// .. or by declaring tuple value first
let tup = (1, 2)
f1 tup
The type of the second function is int -> int -> int, which is the same thing as int -> (int -> int). This means that it is a function that takes int and returns a function that takes int and returns int. This form is called curried form and it allows you to use partial function application as demonstrated by ashays. In fact, the call:
f2 1 2
// Could be written as:
(f2 1) 2
My suspection is that this has something to do with tuples and currying. Basically, a tuple of one item becomes a singular item again, however in our other two cases we have the following:
The first case (f2) is actually a function that takes a single value (x) and returns a value that takes another single function. Here we can see the use of currying from f2 to add10
let add10 = f2 10
let myVal = add10 20
We get an error with the tuple because we have not defined it in such a way as to receive a tuple. In the second example, we have a similar issue, where we defined the function to take a tuple of two values, and it knows how to process those values, but we have passed it two values now instead of the one (a tuple) that it was expecting, and thus we receive an error.
Once again, in the last case, we have a tuple of a single item and so f x and f(x) are effectively the same thing.
I could be wrong in my reasoning, but I believe that's why you're getting your errors.