I have the following Json to deserialize:
{"data":[{"a":[[6902.5,1474],[6903,110],[6903.5,75],[6904,3520],[6904.5,1075],[6905,5296],[6905.5,71],
[6906,1030],[6907,100],[6908,130]],"timestamp":"2020-03-25T10:02:15.098Z","b":[[6902,297],[6901.5,35],
[6900,59],[6899.5,10],[6899,69046],[6898,138210],[6896.5,60],[6896,30],[6894.5,258],[6894,672]]}]}
when I create a type to deserialize to, I can't find how to declare a list of tuples:
{
A : float List List // this compiles
B : (float, float) List // this doesn't compile
}
the elements always come as a pair and are unnamed, no exception.
how can I declare a list of tuples?
A list of tuples would be declared like so:
B : (float * float) list
Related
Consider the following code:
let pair = System.Tuple.Create (10, "foo") // val pair : int * string = (10, "foo")
let tuple = System.Tuple.Create <| (10, "foo") // val tuple : System.Tuple<int * string> = ((10, "foo"))
Why doesn't the two lines yield values of the same type? Does the type of the argument (10, "foo") somehow change between the two lines?
What's the exact difference between int * string and System.Tuple<int * string>?
For 2, at least the latter has null as a value (this is how this question came up). Are there other differences?
There are two different overloads of Tuple.Create:
Tuple.Create<'T1>(item1: 'T1)
Tuple.Create<'T1, 'T2>(item1: 'T1, item2: 'T2)
In the first case you just calling a method with two arguments. So the second Tuple.Create overload is obviously picked. No surprise.
But with piping you first create a tuple instance. And then pass it to Tuple.Create method. This is what happens in the second example
let intermediate : Tuple<int, string> = (10, "foo")
let tuple = Tuple.Create(intermediate)
With a single argument the first Tuple.Create overload will be picked.
Note: star type is a way tuple type names are written in F#. So Tuple<int, string, bool> will be (int * string * bool). It's the same thing.
Your tuple is a tuple of one (1) element, namely the tuple 10,"foo". It is equivalent of
System.Tuple.Create(System.Tuple.Create(10, "foo"))
Your pair on the other hand is a tuple of the two elements 10 and "foo".
So pair has type System.Tuple<int,string> (which is the same as int * string), but tuple has type System.Tuple<System.Tuple<int,string>> (which is System.Tuple<int * string>)
I would like to extend F# Arrays such that I can use arrays without converting to the finite int. Instead I want to work with bigint directly.
I was able to add a second length method to the array type as follows:
type 'T ``[]`` with
member this.LengthI: bigint =
bigint this.Length
member this.Item(index: bigint): 'T =
this.[int index]
However the Item method cannot be called with the .[ ] syntax.
Any ideas how this could be achieved? I this possible at all?
I strongly suspect this isn't possible for native arrays. You can verify yourself that you can overload indexed access just fine for other collections.
If you compile the following code:
let myArray = [| "a" |]
let myList = [ "a" ]
let arrayElement = myArray.[11111]
let listElement = myList.[22222]
and inspect the resulting IL, you'll see that while accessing the list element compiles to a regular virtual call, there is a special CIL instruction for accessing a native array element, ldelem.
//000004: let arrayElement = myArray.[11111]
IL_002c: call string[] Fuduoqv1565::get_myArray()
IL_0031: ldc.i4 0x2b67
IL_0036: ldelem [mscorlib]System.String
IL_003b: stsfld string '<StartupCode$51dff40d-e00b-40e4-b9cc-15309089d437>'.$Fuduoqv1565::arrayElement#4
.line 5,5 : 1,33 ''
//000005: let listElement = myList.[22222]
IL_0040: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string> Fuduoqv1565::get_myList()
IL_0045: ldc.i4 0x56ce
IL_004a: callvirt instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<string>::get_Item(int32)
IL_004f: stsfld string '<StartupCode$51dff40d-e00b-40e4-b9cc-15309089d437>'.$Fuduoqv1565::listElement#5
IL_0054: ret
I would guess that the same compiler logic that special-case array access to that single instruction also bypass any overload resolution involving extension methods and the like.
One way to circumvent this is to wrap the array in a custom type, where overloaded indexers will work as you expect. Making the wrapper type a struct should reduce the performance loss in most cases:
type [<Struct>] BigArray<'T>(array : 'T[]) =
member this.LengthI: bigint =
bigint array.Length
member this.Item
with get(index : int) = array.[index]
and set (index : int) value = array.[index] <- value
member this.Item
with get(index : bigint) = array.[int index]
and set (index : bigint) value = array.[int index] <- value
let bigArray = BigArray myArray
let bigArrayElement = bigArray.[0]
let bigArrayElement2 = bigArray.[bigint 0]
Another one is to upcast the array to the base System.Array class, on which you can then define the same overloaded operator. This removes the need to create a wrapper type and duplicate all members of 'T[], as you can just upcast/downcast the same array object as necessary. However, since the base class is untyped, you will lose type safety and have to box/unbox the elements when using the indexed access, which is quite ugly:
type System.Array with
member this.Item
with get (index : int) = (this :?> 'T[]).[index]
and set (index : int) (value : 'T) = (this :?> 'T[]).[index] <- value
member this.Item
with get(index : bigint) : 'T = (this :?> 'T[]).[int index]
and set(index : bigint) (value : 'T) = (this :?> 'T[]).[int index] <- value
let untypedArray = myArray :> System.Array
let untypedArrayElement = box untypedArray.[0] :?> string
let untypedArrayElement2 = box untypedArray.[bigint 0] :?> string
If I have a square grid (created in WPF/XAML) in any size, with a given number of cells per side, it should be ridiculously easy to calculate the coordinates to a cell that was clicked by getting the mouse cursor position relative to the grid element. As I try to learn F#, I experience some problems with the syntax and would appreciate some input.
Here is an example of what I am trying to do:
// From a mouse event, fetch the position of the cursor relative to a IInputElement
let get_mouse_position (relative_to : IInputElement) (args : Input.MouseEventArgs) : (int*int) =
let position = args.GetPosition relative_to
((Convert.ToInt32(position.X) / cellsPerSide), (Convert.ToInt32(position.Y) / cellsPerSide))
// Get the position of the cursor relative to the grid
let get_cell_coordinates (element : IInputElement) =
get_mouse_position element
However, when I try to use the coordinates retrieved by calling get_cell_coordinates somewhere else where (x,y) coordinates are needed, I get an error that says:
This expression was expected to have type int * int but here has type 'a -> int * int
So, what am I doing wrong and why do I get this polymorph type and not just a tuple of integers?
The type you got is not a "polymorph" type, it's a function type. The reason you got a function of type 'a -> int * int instead of the int * int result you were expecting is because you didn't pass all the parameters to your function, so F# returned a function that expected the rest of the parameters. This is called "partial application", and you can read more about it here:
https://fsharpforfunandprofit.com/posts/currying/
and
https://fsharpforfunandprofit.com/posts/partial-application/
A quick summary of the two articles: in F#, all functions are treated as taking one parameter and returning one result. Yes, ALL functions. When you create a function that appears to take two parameters, F# rewrites it internally. It becomes a function that takes one parameter and returns a second function; this second function takes one parameter and returns the result. A concrete example will probably be useful at this point. Consider this function:
let doubleAndSubtract a b = (a * 2) - b
(Obviously, the parentheses around a * 2 aren't actually needed, but I left them in to make the function unambiguous to read).
Internally, F# actually rewrites this function into the following:
let doubleAndSubtract a =
let subtract b = (a * 2) - b
subtract
In other words, it builds a function that "closes over" (captures) the value of a that you passed in. So the following two functions are completely equivalent:
let explicitSubtract b = (5 * 2) - b
let implicitSubtract = doubleAndSubtract 5
If you type these functions in to the F# interactive prompt and look at the types that it declares each function to have, explicitSubtract has type b:int -> int, and implicitSubtract has type int -> int. The only difference between these two is that the type of explicitSubtract names the parameter, whereas implicitSubtract doesn't "know" the name of its parameter. But both will take an int, and return an int (specifically, 10 minus the parameter).
Now, let's look at the type signature for doubleAndSubtract. If you typed it into the F# interactive prompt, you'll have seen that its type signature is int -> int -> int. In type signatures, -> is right-associative, so that signature is really int -> (int -> int) -- in other words, a function that takes an int and returns a function that takes an int and returns an int. But you can also think of it as a function that takes two ints and returns an int, and you can define it that way.
So, what happened with your code here is that you defined the function like this:
let get_mouse_position (relative_to : IInputElement) (args : Input.MouseEventArgs) : (int*int) = ...
This is a function that takes two parameters (of types IInputElement and Input.MouseEventArgs) and returns a tuple of ints... but that's equivalent to a function that takes one parameter of type IInputElement, and returns a function that takes an Input.MouseEventArgs and returns a tuple of two ints. In other words, your function signature is:
IInputElement -> Input.MouseEventArgs -> (int * int)
When you called it as get_mouse_position element you passed it only a single parameter, so what you got was a function of type Input.MouseEventArgs -> (int * int). The type checker reported this as type 'a -> int * int (changing Input.MouseEventArgs into the generic type name 'a) for reasons I don't want to get into here (this is already rather long), but that's why you got the result you got.
I hope this helps you understand F# functions better. And do read those two articles I linked to; they'll take your understanding another step further.
I solved it by using the static Mouse.GetPosition method to obtain the position of the mouse instead of Input.MouseEventArgs.
The code now looks as follows, if anyone else has the same problem:
// From a mouse event, fetch the position of the cursor relative to a IInputElement
let get_mouse_position (relative_to : IInputElement) : (int*int) =
let position = Mouse.GetPosition relative_to
((Convert.ToInt32(position.X) / cellsPerSide), (Convert.ToInt32(position.Y) / 32))
// Get the position of the cursor relative to the input element
let get_cell_coordinates (element : IInputElement) =
get_mouse_position element
I try to find in Swift documentation where it is defined, but I couldn't.
I expect something like following:
typealias [] = Array
typealias [Element] = Array<Element>
typealias [AnyObject] = Array<AnyObject>
So why it is possible to use [] instead of Array as initializer?
Edit depending on answer
I try to do the same with my custom Person class but it doesn't work:
class Person: ArrayLiteralConvertible {
typealias Element
public init(arrayLiteral elements: Self.Element...)
}
let personNames: Person = ["John", "Mark", "Kris"]
It's defined in the Summary of the Grammar, in the definition of array-literal:
array-literal → [ array-literal-items(opt) ]
array-literal-items → array-literal-item ,(opt) | array-literal-item , array-literal-items
array-literal-item → expression
In more "descriptive" text, this particular case is defined in The Swift Programming Language, Collection Types in the section on Arrays:
Creating an Empty Array
You can create an empty array of a certain type using initializer syntax:
var someInts: [Int] = []
print("someInts is of type [Int] with \(someInts.count) items.")
// Prints "someInts is of type [Int] with 0 items."
Note that the type of the someInts variable is inferred to be
[Int] from the type of the initializer.
To your updated question, the correct syntax (circa Swift 5, though your question is from and older version), would be:
class Person: ExpressibleByArrayLiteral {
required public init(arrayLiteral elements: String...) { ... }
}
You can write it a as a literal everything that conforms to literal protocols . Sets as Array conforms to ArrayLiteralConvertible protocol, you can declare a set by using the same array literal sintax and specifing the type to avoid compiler confusion or they still will be inferred as Array:
let set: Set = ["Hello","Bye"]
To conforms array literal protocol you must provide an initializer:
protocol ArrayLiteralConvertible {
typealias Element
init(arrayLiteral elements: Element...)
}
There is a nice post on NSHipster
Documentation define a literal as:
A literal is the source code representation of a value of a type, such
as a number or string.
Where it a literal first defined? I guess it's the duty of the compiler detect them and substitute with the proper type.
None of the examples I have seen thus far appear to address the problem of marshaling a structure containing a union of structures that contain recursive references. I am attempting to write a marshaler for a structure which contains these and have so far failed.
For example:
typedef enum {
My_StructA = 0x7878,
My_StructB
} MyStructTag;
typedef struct _MyStruct MyStruct;
struct _MyStruct {
MyStructTag discriminator;
union {
struct {
int a;
int b;
} StructA;
struct {
int c;
MyStruct* d;
} StructB;
} MyUnion;
};
I attempted to define the structures as follows:
type MyStructTag =
| My_StructA = 0x7878
| My_StructB = 0x7879
[<Struct; StructLayout(LayoutKind.Sequential)>]
type StructA =
val mutable a : int
val mutable b : int
[<Struct; StructLayout(LayoutKind.Sequential)>]
type StructB =
val mutable c : int
val mutable d : MyStruct
[<Struct; StructLayout(LayoutKind.Explicit)>]
type MyStruct =
[<FieldOffset(0)>] val discriminator : MyStructTag
[<FieldOffset(4)>] val structA : StructA
[<FieldOffset(4)>] val structB : StructB
Note that the reason I bothered to define MyStruct explicitly is to allow myself to make use of Marshal.OffsetOf() and Marshal.SizeOf() when writing the custom marshaler for this structure. From what I have seen, writing a custom marshaler is the only way to handle unions. If I am wrong about that, references would be greatly appreciated!
The error I receive when writing the above code is:
error FS0039: The type 'MyStruct' is not defined
I assume this is because only discriminated union types can be defined recursively. However, I am not aware of any other way to represent these structures in F#.
Thank you in advance for your time.
You've got two problems. First of all, any mutually recursive types (whether discriminated unions, classes, or structs) need to be defined using
type A = ...
and B = ...
rather than
type A = ...
type B = ...
(and note that attributes can come before or after the word type, but only after the word and...). However, if you try this, you'll see that you just get a different error, because structs can't be directly recursive as fields of each other. If struct A had a field which was a struct B and struct B had a field which was a struct A (and either of them had any other fields), then the size would be infinite. Note that this is true of your C code as well - StructB contains a pointer to a MyStruct, not a MyStruct itself. In .NET, you can use an IntPtr for this - in F# you can use the nativeint alias or nativeptr<MyStruct>. Try this:
open System.Runtime.InteropServices
type MyStructTag =
| My_StructA = 0x7878
| My_StructB = 0x7879
[<Struct; StructLayout(LayoutKind.Sequential)>]
type StructA =
val mutable a : int
val mutable b : int
[<Struct; StructLayout(LayoutKind.Sequential)>]
type StructB =
val mutable c : int
val mutable d : nativeptr<MyStruct>
and [<Struct; StructLayout(LayoutKind.Explicit)>]MyStruct =
[<FieldOffset(0)>] val discriminator : MyStructTag
[<FieldOffset(4)>] val structA : StructA
[<FieldOffset(4)>] val structB : StructB