Creating an array of Queue<T> in an F# class - f#

How do I create an array of Queue<float> and initialize it in F#?
I was trying something like this, but it is a weird C# small (besides the fact that the compiler can't resolve the overloading of the Queue constructor).
type MyQueues(size) =
let queues = Queue<float>(capacity:size) array
do
// Initialize queues somehow.

let queues = Array.init arraysize (fun index -> (* initialize queue here *) )
or
let queues = [| for i in 1 .. arraysize -> (* initialize queue here *) |]
In most cases F# compiler will infer the type of array from provided initializing function. arraysize here is a capacity of the array not the queue size which you would provide in initializer function.
let queues = Array.init arraysize (fun index -> new Queue<float>(queuecapacity) )

Related

Partial application with changing of return type

I have a function to read a byte from an array:
let readByte array address = (* []<byte> -> int -> byte *)
(* ... *)
In an other function where I use this function very often, I'd like to do partial application:
let myOtherFunction array =
let readByteAsInt = readByte array
(* ... *)
let x = readByteAsInt address
Basically this works. In my example x is now of type byte but I would need it as an int. In this simple example I could cast the return value when assigning to x but as I said, I use readByteAsInt very often and I don't want to do the cast on every call.
I have tried
let readByteAsInt = int (readByte array)
and
let readByteAsInt = readByte array |> int
but both result in an error when calling readByteAsInt:
FS0003: This value is not a function and cannot be applied
How can I change the return type of the partial application?
Changing the signature of readByte to return an int is not an option as I do need byte elsewhere.
readByte array is a function, and int is another function; you want to compose them so that the output of readByte array becomes the input of int. You can write readByte array >> int - note that it's >> for composition, instead of |> for application.
Like #kaya3 mentioned, you can use function composition with (<<) or (>>). But even without function application or composition, you could just create another function directly with a parameter instead.
let readByteAsInt pos = int (readByte array pos)
let readByteAsInt pos = readByte array pos |> int
Or the function compositon way
let readByteAsInt = int << readByte array
let readByteAsInt = readByte array >> int
Keep in mind, that function composition, does not always work in F# when the function has a generic input, then you must define a function with arguments explicitly.

How can a cacheline sized struct wrapping a mutable, volatile int64 be created in F#?

I want to create a cacheline sized struct wrapping a mutable, volatile int64 in F#. I’ve tried various struct definitions including the one below, but can't get anything to compile.
[<Struct; StructLayout(LayoutKind.Explicit, Size = 64)>]
type MyStruct1 (initVal:int64) =
[<VolatileField>]
let mutable value = initVal
member x.Value
with get () = value
and set(valIn) = value <- valIn
which gives this error: "Structs cannot contain value definitions because the default constructor for structs will not execute these bindings.
consider adding additional arguments to the primary constructor for the type". I can't see what additional arguements I could add to the primary constructor above.
Any ideas?
The struct definition could be
[<Struct; StructLayout(LayoutKind.Explicit, Size = 64)>]
type MyStruct =
[<FieldOffset(0)>]
val mutable value : int64
new(initVal:int64) = { value = initVal }
member x.Value
with get() = x.value
and set(valIn) = x.value <- valIn
but then, [<VolatileField>] is not allowed on val bindings and structs can't contain let bindings.
TL;DR: AFAIK this is impossible in F#
As pointed out by #V.B. you could use Interlocked which gives a superset of volatiles guarantees (stronger guarantees ≈ more overhead). It might then be better to privateize value to prevent (accidental) writes circumventing the barrier:
[<Struct; StructLayout(LayoutKind.Explicit, Size = 64)>]
type MyStruct =
[<FieldOffset(0)>]
val mutable private value : int64
new(initVal:int64) = { value = initVal }
member public x.Value
with get() = Interlocked.Read(&x.value)
and set(valIn) = Interlocked.Exchange(&x.value, valIn) |> ignore
Interlocked gives similar guarantees as volatile, see this question.
open System.Threading
[<Struct; StructLayout(LayoutKind.Explicit, Size = 64)>]
type MyStruct =
[<FieldOffset(0)>]
val mutable value : int64
new(initVal:int64) = { value = initVal }
member x.Value
with get() = Interlocked.Read(&(x.value))
and set(valIn) = Interlocked.Exchange(&(x.value),valIn) |> ignore

How can I dynamically unbox a value in F#?

I am trying to achieve the automatic/dynamic cast in the fourth line below:
let a = 1 // type: int
let b = box a // type: obj
b.GetType() // System.Int32, so it is perfectly aware what it is!
let c = unbox b // fails....
The following would would work in the final line above BUT would require me to know and explicitly mark ahead-of-time the primitive/value type that I am working with (which I am trying to avoid):
let c1:int = unbox b
let c2 = b :?> int
While b knows at run-time what it is, the compiler doesn't, because it's an obj.
If you know, at compile time, what it is, you can unbox it like this:
let a = 1
let b = box a
b.GetType()
let c = unbox<int> b
c is now an int.
unbox only does anything if the type can be explicitly or implicitly determined at compile time. Here it will implicitly (and wrongly) try to convert the object to a string, as that's how it is used in the subsequent line.
let a = 1
let b = box a
b.GetType()
let c = unbox b
printf "%s" c
This of course gives a runtime error because it is not a string.
There's no way to have unbox convert to "what it actually is under the hood", as there's no definite way of determining this at compile time. There may be another way to do what you're trying to do though, if you can provide more details.
If you're wanting to, say create a generic unboxed list from boxed objects, you can do something like this:
let addToList (l: 'a list) (o: obj) = // type annotations optional
let o' = unbox o // unboxes to generic type 'a
o'::l
let l = [1;2;3]
let b = box 4
let l' = addToList l b // l' is list<int>, not list<obj>
let l2 = [1.;2.;3.]
let b2 = box 4.
let l2' = addToList l2 b2 // l2' is list<float>
// but as above you still have to be careful
let lcrash = addToList l b2 // crash

Why does FSharp interactive allow mutable let?

In FSI I type
> let a = 10;;
val a : int = 10
> let a = a + 1;;
val a : int = 11
Looks like I have a mutable variable here? Am I missing something?
It is not a mutable value. But you use the shadowing : in F#, value shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope.
If you want to have a mutable value, there is a syntaxe in F# :
let mutable a = 10
a <- a + 1
As already explained by Arthur, what you see is shadowing which means that the original "variable" named a is hidden by a new "variable" also named a (I use variable in quotes, because they are actually immutable values).
To see the difference, you can capture the original value in a function and then print the value after hiding the original value:
> let a = 10;; // Define the original 'a' value
val a : int = 10
> let f () = a;; // A function captures the original value
val f : unit -> int
> let a = 42;; // Define a new value hiding the first 'a'
val a : int = 42
> f();; // Prints the original value - it is not mutated!
val it : int = 10
Sadly, you cannot use exactly the same code to see how let mutable behaves (because F# does not allow capturing mutable references in closures), but you can see mutation when you use reference cells (that is, a simple object that stores mutable value in the heap):
> let a = ref 10;; // Create a mutable reference cell initialized to 10
val a : int ref = {contents = 10;}
> let f () = !a;; // A function reads the current value of the cell
val f : unit -> int
> a := 42;; // Overwrite the value in the cell with 42
val it : unit = ()
> f();; // Prints the new value - it is mutated
val it : int = 42
You can run the code line-by-line in F# interactive, but it will do exactly the same thing when you copy the entire snippet (the input lines) and place them in normal F# code - e.g. inside a function or a module. The ;; is just to end the line in the F# interactive input (I typed the code in the F# Interactive window), but it is not needed in normal code, because F# uses indentation to find out where a statement ends.

'mutable' in type definition

Why is disabled types like
type t = A of int | B of string * mutable int
while such types are allowed:
type t = A of int | B of string * int ref
The question is, how would you modify the value of a mutable element of discriminated union case? For ref types, this is quite easy, because ref is a reference cell (a record actually) which contains the mutable value:
match tval with
| B(str, refNum) -> refNum := 4
We extract the reference cell and assign it to a new symbol (or a new variable) refNum. Then we modify the value inside the ref cell, which also modifies tval, because the two references to the cell (from discriminated union case and from refNum variable) are aliased.
On the other hand, when you write let mutable n = 0, you're creating a variable, which can be directly mutated, but there is no cell holding the mutable value - the variable n is directly mutable. This shows the difference:
let mutable a = 10
let mutable b = a
b <- 5 // a = 10, b = 5
let a = ref 10
let b = a
b := 5 // a = 5, b = 5 (because of aliasing!)
So, to answer your question - there is no way to directly refer to the value stored inside the discriminated union case. You can only extract it using pattern matching, but that copies the value to a new variable. This means that there isn't any way you could modify the mutable value.
EDIT
To demonstrate limitations of mutable values in F#, here is one more example - you cannot capture mutable values inside a closure:
let foo() =
let mutable n = 0
(fun () -> n <- n + 1; n) // error FS0407
I think the reason is same as with discriminated union cases (even though it's not as obvious in this case). The compiler needs to copy the variable - it is stored as a local variable and as a field in the generated closure. And when copying, you want to modify the same variable from multiple references, so aliasing semantics is the only reasonable thing to do...
Ref is a type (int ref = ref<int>). Mutable is not a type, it's a keyword that allows you to update a value.
Example:
let (bla:ref<int>) = ref 0 //yup
let (bla:mutable<int>) = 3 //no!

Resources