I am trying to develop a random number "generator" in F#.
I successfully created the following function:
let draw () =
let rand = new Random()
rand.Next(0,36)
This works fine and it generates a number between 0 and 36.
However, I am trying to create a function that runs this function several times.
I tried the following
let multipleDraws (n:int) =
[for i in 1..n -> draw()]
However, I only get a single result, as draw is evaluated only once in the for comprehension.
How could I force multiple executions of the draw function?
The problem is with the Random type. It uses the computer's time to generate a seed and then generate the random numbers. Since practically the time of the calls is identical, the same seed is generated and so are also same numbers returned.
This will solve your problem:
let draw =
let rand = new Random()
fun () ->
rand.Next(0,36)
And then:
let multipleDraws (n:int) =
[for i in 1..n -> draw()]
Adding this to help explain Ramon's answer.
This code uses a lambda function.
let draw =
let rand = new Random()
fun () ->
rand.Next(0,36)
It may be easier to understand what's happening if you give the lambda function a name.
let draw =
let rand = new Random()
let next() =
rand.Next(0,36)
next
The variable draw is being assigned the function next. You can move rand and next out of the scope of draw to see the assignment directly.
let rand = new Random()
let next() =
rand.Next(0,36)
let draw = next
You can see from the above code that in Ramon's answer new Random is only called once while it is called many times in SRKX's example.
As mentioned by Ramon Random generates a sequence of numbers based on a random seed. It will always generate the same sequence of numbers if you use the same seed. You can pass random a seed like this new Random(2). If you do not pass it a value it uses the current time. So if you call new Random multiple times in a row without a seed it will most likely have the same seed (because the time hasn't changed). If the seed doesn't change then the first random number of the sequence will always be the same. If you try SRKX's original code and call multipleDraws with a large enough number, then the time will change during the loop and you will get back a sequence of numbers that changes every so often.
Related
I'm pretty new to functional programming so this might be a question due to misconception, but I can't get my head around this - from an OOP point of view it seems so obvious...
scenario:
Assume you have an actor or micro-service like architecture approach where messages/requests are sent to some components that handle them and reply. Assume now, one of the components stores some of the data from the requests for future requests (e.g. it calculates a value and stores it in a cache so that the next time the same request occurs, no calculation is needed).
The data can be hold in memory.
question:
How do you in functional programming in general, and especially in f#, handle such a scenario? I guess a static dictionary is not a functional approach and I don't want to include any external things like data stores if possible.
Or more precise:
If an application creates data that will be used later in the processing again, where do we store the data?
example: You have an application that executes some sort of tasks on some initial data. First, you store the inital data (e.g. add it to a dictionary), then you execute the first task that does some processing based on a subset of the data, then you execute the second task that adds additional data and so on until all tasks are done...
Now the basic approach (from my understanding) would be to define the data and use the tasks as some sort of processing-chain that forward the processed data, like initial-data -> task-1 -> task-2 -> ... -> done
but that does not fit an architecture where getting/adding data is done message-based and asynchronous.
approach:
My initial approach was this
type Record = { }
let private dummyStore = new System.Collections.Concurrent.ConcurrentBag<Record>()
let search comparison =
let matchingRecords = dummyStore |> Seq.where (comparison)
if matchingRecords |> Seq.isEmpty
then EmptyFailedRequest
else Record (matchingRecords |> Seq.head)
let initialize initialData =
initialData |> Seq.iter (dummyStore.Add)
let add newRecord =
dummyStore.Add(newRecord)
encapsulated in a module that looks to me like an OOP approach.
After #Gustavo asked me to provide an example and considering his suggestion I've realized that I could do it like this (go one level higher to the place where the functions are actually called):
let handleMessage message store =
// all the operations from above but now with Seq<Record> -> ... -> Seq<Record>
store
let agent = MailboxProcessor.Start(fun inbox->
let rec messageLoop store = async{
let! msg = inbox.Receive()
let modifiedStore = handleMessage msg store
return! messageLoop modifiedStore
}
messageLoop Seq.empty
)
This answers the question for me well since it removed mutability and shared state at all. But when just looking at the first approach, I cannot think of any solution w/o the collection outside the functions
Please note that this question is in f# to explain the environment, the syntax etc. I don't want a solution that works because f# is multi-paradigm, I would like to get a functional approach for that.
I've read all questions that I could find on SO so far but they either prove the theoretical possibility or they use collections for this scenario - if duplicated please point me the right direction.
You can use a technique called memoization which is very common in FP.
And it consists precisely on keeping a dictionary with the calculated values.
Here's a sample implementation:
open System
open System.Collections.Concurrent
let getOrAdd (a:ConcurrentDictionary<'A,'B>) (b:_->_) k = a.GetOrAdd(k, b)
let memoize f =
let dic = new ConcurrentDictionary<_,_>()
getOrAdd dic f
Note that with memoize you can decorate any function and get a memoized version of it. Here's a sample:
let f x =
printfn "calculating f (%i)" x
2 * x
let g = memoize f // g is the memoized version of f
// test
> g 5 ;;
calculating f (5)
val it : int = 10
> g 5 ;;
val it : int = 10
You can see that in the second execution the value was not calculated.
This code is printing float numbers in the file with this format f,ffffff (with comma) and the numbers are in a row, but I need to print it like this f.ffffff (with dot) and after each number skip a line, so each number has its own line. Any ideas on how do I do it?
CODE EDITED
module writeFiles =
let (w:float[]) = [|-1.3231725; 1.052134922; 1.23082055; 1.457748868; -0.3481141253; -0.06886428466; -1.473392229; 0.1103078722; -1.047231857; -2.641890652; -1.335060286; -0.9839854216; 0.1844535984; 3.087001584; -0.008467130841; 1.175365466; 1.637297522; 5.557832631; -0.2906445452; -0.4052301538; 1.766454088; -2.604325471; -1.807107036; -2.471407376; -2.204730614;|]
let write secfilePath=
for j in 0 .. 24 do
let z = w.[j].ToString()
File.AppendAllText(secfilePath, z)
//File.AppendAllLines(secfilePath, z)
done
There is couple things that could be done better in your code.
You're opening the file over and over again every time you add a number
z does not need to be mutable
You can pass format pattern and/or culture to ToString call
You can iterate over filterMod.y instead of for loop and array indexer access
I would probably go with something more like
module writeFiles =
let write secfilePath=
let data = filterMod.y
|> Array.map (fun x -> x.ToString(CultureInfo.InvariantCulture))
File.AppendAllLines(secfilePath, data)
It prepares an array of strings, where every number of filterMod.y gets formatted using CultureInfo.InvariantCulture, which will make it use . as decimal separator. And later on it uses AppendAllLines to write the whole array to the file at once, where every element will be written in a separate line.
I wanted to filter a Deedle dataframe based on a list of values how would I go about doing this?
I had an idea to use the following code below:
let d= df1|>filterRowValues(fun row -> row.GetAs<float>("ts") = timex)
However the issue with this is that it is only based on one variable, I then thought of combining this with a for loop and an append function:
for i in 0.. recd.length -1 do
df2.Append(df1|>filterRowValues(fun row -> row.GetAs<float>("ts") = recd.[i]))
This does not work either however and there must be a better way of doing this without using a for loop. In R I could for instance using an %in%.
You can use the F# set type to create a set of the values that you are interested. In the filtering, you can then check whether the set contains the actual value for the row.
For example, say that you have recd of type seq<float>. Then you should be able to write:
let recdSet = set recd
let d = df1 |> Frame.filterRowValues (fun row ->
recdSet.Contains(row.GetAs<float>("ts"))
Some other things that might be useful:
You can replace row.GetAs<float>("ts") with just row?ts (which always returns float and works only when you have a fixed name, like "ts", but it makes the code nicer)
Comparing float values might not be the best thing to do (because of floating point imprecisions, this might not always work as expected).
I am defining a stopwatch in F#:
open System.Diagnostics
let UptimeStopwatch = Stopwatch.StartNew()
and I am printing every 3 seconds with
printfn "%A" UptimeStopwatch.Elapsed
and every time i'm getting "00:00:00.0003195" or something similarly small. Is F# calling the constructor every time I reference UptimeStopwatch? If so, how do I get around this ad achieve the desired result? This is a confusing intermingling of functional and imperative programming.
F# seems to interpret statements like
let MyFunction = DoSomething()
and
let MyFunction() = DoSomething()
differently. The first binds the return value of DoSomething() to the variable MyFunction, and the second binds the action DoSomething() to the function MyFunction().
My usage of UptimeStopwatch was correct, and the error was elsewhere in my implementation.
I see you already found a problem elsewhere in your code, but the two lines in your question still take some time to run and, interestingly, you can make the overhead smaller.
When I run the two lines in your sample, it prints a value around 0.0002142. You can make that smaller by storing the elapsed time using let, because there is some overhead associated with constructing a representation of the printf format string (the first argument):
let UptimeStopwatch = Stopwatch.StartNew()
let elapsed = UptimeStopwatch.Elapsed
printfn "%A" elapsed
This prints on average a number around 0.0000878 (two times smaller). If you use Console, the result is similar (because the Elapsed property is obtained before Console is called and nothing else needs to be done in the meantime):
let UptimeStopwatch = Stopwatch.StartNew()
System.Console.WriteLine(UptimeStopwatch.Elapsed)
For learning purposes I am trying out running a simulation as a sequence with F#. Starting from a sequence of random numbers, map is a straightforward way to generate a sequence of states if the states do not depend on the previous states. Where I run into a problem is when I try to do something like:
State(i+1) = F (State(i), random number)
I managed to get something working by using unfold, passing in the random generator along the lines of
let unfold (day:State,rnd:Random) =
let rand = rnd.NextDouble()
let nextDay = NextState day rand
Some (nextDay, (nextDay, rnd))
However, at least to my inexperienced eyes, something about passing around the Random instance seems fishy. Is there a way to achieve something similar but passing in a sequence of random numbers, rather than the generator?
I think your hunch about passing around a Random instance as being fishy is fair: when mutable state is useful it's a good idea to isolate it, so that you benifit from purity as much as possible.
We can isolate the state here by creating a sequence which yields a different set of random numbers upon each iteration
open System
let rndSeq =
seq {
//note that by putting rnd inside seq expression here, we ensure that each iteration of the sequence
//yields a different sequnce of random numbers
let rnd = new Random()
while true do yield rnd.NextDouble()
}
then, you can use Seq.scan to iterate the random sequence by mapping elements using a function which is informed by the previous element which was mapped.
let runSimulation inputSeq initialState =
inputSeq
|> Seq.scan
(fun (previousState:State) (inputElement:float) -> NextState previousState inputElement)
initialState
runSimulation rndSeq initialState //run the simulation using a random sequence of doubles greater than or equal to 0.0 and less than 1
You can see as an added bonus here that your simulated input and simulation implementation are no longer bound together, you can run your simulation using any input sequence.
I'd agree with BrokenGlass that using a global Random instance feels allright in this case. This is a reasonably localized use of mutable state, so it shouldn't be confusing.
As an alternative to unfold, you can consider writing the computation explicitly:
let simulationStates =
let rnd = new Random()
let rec generate (day:State) = seq {
let rand = rnd.NextDouble()
let nextDay = NextState day rand
yield nextDay
yield! generate nextDay }
generate InitialState
Note that the rnd value is local variable with a scope limited only to the definition of simulationStates. This is quite nice way to keep mutable state separate from the rest of the program.
The version using unfold is probably more succinct; this one may be easier to read, so it depends on your personal style preferences.
Might be against the spirit, but I would just use a global Random instance in this case - alternatively you could define a sequence of random numbers like this:
let randomNumbers =
seq {
let rnd = new Random();
while true do
yield rnd.NextDouble();
}