Using BlockingCollection<'a>.TryTake in F# - f#

This is related to an old question:
How to consume BlockingCollection<'a>.TryTake in F#
where the answer is more or less that we can't use it because the byref part should be at the end of the parameter list to make it possible.
8 years have passed since this question: are there any similar blocking queues with a timeout that I can use in F#?

You can use TryTake from F# without issues, but you can't use it as tuple returns. For exmaple, in FSI, this code:
open System.Collections.Concurrent
let bc = new BlockingCollection<int>()
let mutable item = 0
bc.Add 42
let success = bc.TryTake(&item, 100)
Will work fine, and result in the following output:
val bc : BlockingCollection<int>
val mutable item : int = 42
val success : bool = true

Related

Type inference F# - how to generate fresh variables?

i'm trying to develop the algorithm W in f# for type inference, but i would like to understand how to write the function for generating fresh variables properly.
Actually my function is
let counter = ref -1
let generate_fresh_variable () : string =
let list_variables = ['a' .. 'z'] |> List.map string
counter.Value <- !counter + 1
list_variables.Item(!counter)
but i'm not satisfy with this solution, someone can give me other better ideas?
If you really want to do this with an impure function, I would write it like this:
let mutable counter = -1
let generate_fresh_variable () =
counter <- counter + 1
counter + int 'a'
|> char
|> string
Notes:
Reference cells are obsolete. If you need impurity, use mutable variables instead. (Alternatively, if you really want to stick with a reference cell, the canonical way to update it is with :=, rather than assigning directly to the underlying Value.)
There's no need to maintain a list of potential variable names (and there's especially no need to rebuild the entire list each time you generate a fresh variable).
What happens if you need more than 26 variables?
If you wanted to use some more sophisticated F# tricks, you could create an inifinte sequence of names using a sequence expression (which makes it very easy to handle the looping and dealing with >26 names):
let names = seq {
for i in Seq.initInfinite id do
for c in 'a' .. 'z' do
if i = 0 then yield string c
else yield string c + string i }
A function to get the fresh name would then pick the next name from the sequence. You need to do this using the underlying enumerator. Another nice trick is to hide the state in a local variable and return a function using lambda:
let freshName =
let en = names.GetEnumerator()
fun () ->
ignore(en.MoveNext())
en.Current
Then just call freshName() as many times as you need.

F# - Use C# methods with out parameter (within arrays and void return)

I've read the-f-equivalent-of-cs-out but still I can't make it work for my case (the simplest solution/syntax).
I have this method in a C# project:
//<Project Sdk="Microsoft.NET.Sdk">
//<TargetFrameworks>netcoreapp3.1;netstandard2.0</TargetFrameworks>
public static void ABC(out byte[] a, out byte[] b, byte[] c)
{
var aaa = new byte[10];
var bbb = new byte[10];
a = aaa;
b = bbb;
}
Now, I want to use it in a F# project:
I'm using FSharp.Core 4.7.2
(* <Project Sdk="Microsoft.NET.Sdk">
<TargetFrameworks>netcoreapp3.1;netstandard2.0</TargetFrameworks> *)
let a,b = ABC(c)
I'm imitating the syntax of TryParse and this compiles without errors:
let success, number = System.Int32.TryParse("0")
The compiler on my ABC(c) call complains about the fact the signature asks for 3 parameters, not 1.
Compared to the TryParse I see 2 differences:
It does not return void
It uses Array objects
The compiler accepts this syntax:
let a = Array.empty<byte>
let b = Array.empty<byte>
ABC(ref a, ref b, c)
but:
I think it is not correct to use ref here, not in this way (because a and b are not mutable)
I'd like to use the clean syntax similar to TryParse and I WANT to know why it does not work here
I can change the C# project code, but replacing all the out parameters in that proejct will be a second step and maybe a new qeustion if I have difficulties or doubt.
[Update: parameter position]
I played a little with this and seems like I found when the "simple" syntax (without passing ref parameters) is broken.
public static void TryParseArray(string input, out int[] result) {
result = new int[0];
}
public static void TryParseArray_2(out int[] result, string input) {
result = new int[0];
}
let arr = csharp.TryParseArray("a") // OK
let arr = csharp.TryParseArray_2("a") // ERROR
It seems like the out parameter must be at the end (= not followed by normal parameters) in the C# methods, to make possible for F# to use them as returned tuple.
You correctly noticed that the "simplified" F# syntax for turning out parameters into returned tuples only works in very limited situations - only when you have one parameter and it is the last one. In other words, this feature helps with some common patterns, but it does not fully replace out parameters.
If you want to use out parameter in F#, you can either pass a reference to a local mutable variable using the &var syntax, or you can specify a reference cell of type int ref as an argument. The following shows the two options using the standard TryParse method:
// Using a local mutable variable
let mutable n = 0
Int32.TryParse("42", &n)
printfn "Got: %d" n
// Using a reference cell initialized to 0
let n = ref 0
Int32.TryParse("42", n)
printfn "Got: %d" n.Value

F# how to write a function which provides a counter number in serial order

So if you go to a bank there is a device from which you can pull a number out.
I want to write a function like that. So everytime this function is called we get a next number in the series.
So if this function is called first time, we get 1. second time we get 2.... so on and so forth.
this is what I have written so far
let X =
let myseq = seq {1 .. 100}
let GetValue =
Seq.head (Seq.take 1 myseq)
GetValue;;
let p = X;;
p;;
p;;
p;;
But it always return 1. My hope was that since the sequence is a closure, everytime I do a take, I will get the next number.
I also tried this
let X =
let mutable i = 1
let GetValue =
i <- i + 1
i
GetValue;;
let p = X;;
p;;
p;;
p;;
This one only prints 2...
You have to return a function. And to it, you have to pass something every time, i.e. your +1 has to be deferred.
let factory =
let counter = ref 0
fun () ->
counter.Value <- !counter + 1
!counter
and now you get
> factory();;
val it : int = 1
> factory();;
val it : int = 2
doing it this way has the nice side-effect, that you completely hide the mutable reference cell inside the function and thus there is no way to somehow tamper with your counter.
Just for a reference, if you wanted a version that uses sequences (just like the first approach in your question), you can do that using the IEnumerable interface:
let factory =
// Infinite sequence of numbers & get enumerator
let numbers = Seq.initInfinite id
let en = numbers.GetEnumerator()
fun () ->
// Move to the next number and return it
en.MoveNext() |> ignore
en.Current
It behaves the same way as factory in Daniel's answer. This still uses mutable state - but it is hidden inside the enumerator (which keeps the current state of the sequence between MoveNext calls).
In this simple case, I'd use Daniel's version, but the above might be handy if you want to iterate over something else than just increasing numbers.
You need to move the variable outside the declaration. You also need to declare a function so that it gets evaluated each time it is called.
let mutable i = 1
let X() =
i <- i + 1
i
This ensures that the function is called each time and that the variable is correctly incremented.

Calling generic function with 'params' from F# (Observable.StartWith)

Edit: Note that, as Daniel and latkin noted in an answer and a comment below, this question involved a bug in F# that seems to have been fixed in early 2014.
I'm trying to write a curried wrapper for Observable.StartWith. I'm using the prerelease Reactive Extensions 2.0, and the VS11 beta. My desired result would be startWith : 'a -> IObservable<'a> -> IObservable<'a>. The obvious implementation would be something like:
let startWith
(value : 'a)
(observable : IObservable<'a>)
: IObservable<'a> =
Observable.StartWith(observable, [| value |])
The intended overload of Observable.StartWith is StartWith<'TSource>(source : IObservable<'TSource>, params values: 'TSource[]) : IObservable<'TSource>.
The compiler throws a confusing error: This method expects a CLI 'params' parameter in this position. 'params' is a way of passing a variable number of arguments to a method in languages such as C#. Consider passing an array for this argument.
I am passing an array. I also tried not passing an array, by omitting the [| |], which leads to a unique-overload-resolution failure. (Presumably due to the possibility that 'a could be System.Reactive.Concurrency.IScheduler, matching the other overload.) I also tried using F# 2.0/VS2010, which gives the same result. I couldn't locate any online discussion of this sort of situation or of the compiler error message.
I can't think of any other way to implement this. Note that in cases where the type parameter can be determined, it's not a problem. For instance, let prependZero : int -> IObservable<int> -> IObservable<int> = fun n o -> o.StartWith(n) works fine. But a generic version would be nice.
It looks like a problem with type inference surrounding generic param arrays. Even a simple case, not involving overload resolution, has problems:
type A() =
static member M<'T>([<ParamArray>] args: 'T[]) = args
//None of these work
let m1 arg = A.M([|arg|])
let m2 args = A.M(args)
let m3<'T> (args:'T[]) = A.M<'T>(args)
Non-generic versions work:
type B() =
static member M([<ParamArray>] args: obj[]) = args
//Both of these are okay
let m1 arg = B.M([|arg|])
let m2 args = B.M(args)
EDIT
I emailed fsbugs and they responded that this is a bug. Here are some workarounds they suggested.
let m1 arg = A.M<obj>([|arg|])
let m2 args = A.M<obj>(args)
let m3 (args:obj[]) = A.M<obj>(args)
let m4 (arg:obj) = A.M<obj>(arg)
let m5 arg1 arg2 = A.M<obj>(arg1,arg2)
let m6 (arg1:'T) = A.M<'T>(arg1)
let m7 (arg1:'T) (arg2:'T) = A.M<'T>(arg1,arg2)
let m8 (arg1:'T) (arg2:'T) = A.M(arg1,arg2)
let m9 (arg1:'T) = A.M(arg1)
let m10<'T> arg1 arg2 = A.M<'T>(arg1,arg2)
let m11<'T> (arg1:'T) (arg2:'T) = A.M<'T>(arg1,arg2)
You do not need to wrap your single value into single element array in order for it to match the last ParamArray argument of Observable.StartWith, just scalar value is OK (these samples may help to understand why).
But then generic type of value creates an ambiguity between two available overloads for Observable.StartWith. Disambiguation can be achieved through forcing of three-agrument overload by explicitly placing the implicit type of IScheduler from the two-argument overload to the argument list, prepending the value, as below:
let startWith (value: 'a) observable =
Observable.StartWith(observable, Scheduler.CurrentThread, value)
Now your code should compile and work. A quick check confirms this:
Observable.Range(1,2)
|> startWith 10
|> fun x -> x.Subscribe(printf "%d ")
outputs as expected 10 1 2.
Update
For Rx 2.0 beta the Scheduler reference would be slightly different, the rest of the answer stays unchanged:
let startWith (value: 'a) (observable: IObservable<'a>) =
Observable.StartWith(observable, Concurrency.Scheduler.CurrentThread, value)

F# mutable function arguments

Is there a way to have mutable function arguments in F#, that would allow something like
let mutable i = 9
let somefun n = n <- 12; ()
somefun i
(* *not* a real-world example *)
I do understand that this can be made to work by wrapping it into a record type
type SomeRec = { mutable i: int }
let ri = { i = 9 }
let someotherfun r = r.i <- 12; ()
and that this can be done in a similar fashion for class members. However, even after browsing through the whole F# Language Specification (yes, I did!), there seems to be no syntax to allow the first case, and the compiler appears to be quite unhappy about my trying this. I was hoping there would be some sort of type annotation, but mutable cannot be used in such.
I also know that I should not be doing this sort of thing in the first place, but the first case (int binding) and the second (record type) are semantically identical, and any such objection would hold for both cases equally.
So I think that I am missing something here.
You can use ref as arguments
let v = ref 0
let mutate r =
r := 100
mutate v
printfn "%d" !v
Or byref keyword
let mutable v = 0
let mutate (r : byref<_>) =
r <- 100
mutate &v
printfn "%d" v
Use byref keyword which is equivalent to C# ref.
See Passing by reference.

Resources