In this previous question I learnt that in F# an array<'T> is not the same as System.Array.
VS tells me that array<'T> inherits System.Array and has the full name Microsoft.FSharp.Core.array<_> and some additional Interfaces.
However MSDN says that array<'T> is a type abbreviation of System.Array. And that it has the notation arr.[i] to get and set items.
So for my lesson, is array<'T> a type abbreviation that includes type extensions and additional Interfaces? Where is the best place to look this up ?
The type array<'T> is an abbreviation, but not for the base type System.Array but for another generic type that represents arrays in F#, which is written as 'T[].
This means that
System.Array is the non-generic base type (where you cannot use indexing and you can only get elements as objects)
'T[] and array<'T> mean exactly the same thing. They are the generic type which supports indexing and you get 'T values from it.
Related
Is there a way (I'm sure there is out of runtime check...) to specify that a parameter or a variable in general conforms to multiple types? to avoid doing something such as
work (a_printer: PRINTER; a_scanner: SCANNER)
do
a_printer.print
a_scanner.scan
-- OR without second parameter
if attached {SCANNER} a_printer as l_scanner then
l_scanner.scan
else
throw RuntimeError
end
end
If feature work belongs to a class that may have formal generic parameters, it could be defined as taking one argument of the corresponding formal generic type:
class X [D -> {PRINTER, SCANNER}] feature
work (device: D)
do
device.scan
device.print
end
end
Then, at the caller site, one could make the call
x.work (multi_function_device)
where x has an appropriate type, e.g. X [MULTI_FUNCTION_PRINTER].
If work could also be declared and implemented as a class feature, the temporary variable could be avoided:
{X [like multi_function_device]}.work (multi_function_device)
If the auxiliary class X is not an option, the current version of the language provides no means to declare an argument as conforming to more than 1 type (e.g., work (d: {PRINTER, SCANNER})), so you would have to resort to preconditions like
work (p: PRINTER)
require
attached {SCANNER} p
do
check
from_precondition: attached {SCANNER} p as s
then
s.scan
end
p.print
end
I think that, if possible, you should use a common ancestor to your multiple types. If you cannot (if you are using library types), you can create descendant classes (MY_PRINTER inherit from PRINTER and DEVICE and MY_SCANNER inherit from SCANNER and DEVICE). Another way is to use ANY as the type, but it is not the best solution.
I am trying to deserialize an array of JSON objects with GSON. So the simple call:
val arrayOfFoo = gson.fromJson(source, Array<Foo<*>>::class.java>)
should do the trick. But type erasure tells us, that Foo<*> does not exist at runtime, so the error "Only class literals are allowed on the left hand side of a class literal" pops up. Well, so the solution must be:
val arrayOfFoo = gson.fromJson<Array<Foo<*>>>(source, Array::class.java)
Unfortunatelly, now the Kotlin compiler magic - that turns arrays of Wrapper types into primitive arrays - can not be sure what to do and tells us:
"Array class literals require a class type. Please specify one in angle brackets".
But, wait: This is, what did not work a second ago. Using
Array<Foo>::class.java
does not work, too, since now the compiler tells us: "One type argument is expected for Foo".
I personally can not see a way to solve that. Is it impossible to give a class literal of a typed array, which's type also expects a type parameter?
You can get the array class from an array instance, for example either one of
arrayOf<Foo<*>>()::class.java
java.lang.reflect.Array.newInstance(Foo::class.java, 0)::class.java
The basic problem: You need to specify the type of your array. This is done using a TypeToken in Gson.
I hope this helps:
val listType = object : TypeToken<Array<String>>() {}.type
val json = """["1"]"""
val yourClassList :Array<String> = Gson().fromJson(json, listType)
print(yourClassList)
Note that for primitives, it is simpler: Gson().fromJson(json, IntArray::class.java)
I'm trying to create an array of Regex objects, like so: Regex[] regexes;.
The compilation fails with main.d(46): Error: template std.regex.Regex(Char) is used as a type.
I find the documentation cryptic. All I understand is that templates generate code on compilation, but I don't see what's preventing me from creating an array of Regex.
There's an existing question on StackOverflow with the same problem, but it deals with C++, not D.
You cannot create a regex object without first instantiating the template with a type. this is because the actual type is generated at compile time based on the instantiation type you give. Regex itself is not an actual type, it is just a template function allowing you to generate a type when instantiated.
In this case you probably want to change:
Regex[] regexes;
into:
Regex!char[] regexes;
to tell the compiler that your regex contains chars as opposed to some derived type. This means specifically you are instantiating the Regex template with the type char.
Take the F# following code:
type Blah<'T>(objects : 'T array) as this = // whatever
When I try to use that type in a XAML document, there is no type associated with the generic parameter, and it's ugly. I think the compiler complains, too:
<ns:Blah foo="bar"/>
So, I try to alias the type like so (at the bottom of my Blah.fs file):
type StuffBlah = Blah<Stuff>
Then when I use it in the same way in my XAML document, the type is not found to exist:
<ns:StuffBlah foo="bar"/>
Why is that? Is there a cleaner, more elegant way to do this? I'm still getting the hang of Silverlight, XAML, and F#, so any advice would be greatly appreciated. Thanks.
The reason the StuffBlah version doesn't work is that particular piece of F# syntax creates a type alias only for the F# project vs. creating an actual type. Since the name is not visible at the IL level as an actual type it is not accessible to Silverlight or XAML in general.
One way to work around this is to create StuffBlah as a first class type which derives from Stuff<'T>. Not ideal at all but it will work.
I'm puzzled about arrays in C#.
I can't find any documentation on MSDN about for example the object double[].
I do find documentation about int, array, collections, ... but can't find out of what type double[] is. If I do double[] a = new double[10]; a.GetType(), I find that the type of a is System.Double[]
I believe that the type is not System.Double[], but must be some descendent of an object or interface in the System.Collections namespace or the System.Collections.Generic namespace. My best guess is that a double[] is a type that implements the interface System.Collections.IList, but I'm not sure at all.
So, could anyone explain me what kind of object an array of doubles (so an object double[]) really is? What are it's base classes, which interfaces does it implement, ...
Where could I find documentation on arrays of objects defined as int[], ..., object[] ?
Thanks!
Array is a base class for all types of arrays int, double, string whatever, the base class for System.Array is System.Object. so the correct type is System.Double[]. It implements the ICloneable,
IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable interfaces as stated on msdn.
The main difference between arrays and collection is that arrays cannot be changed in size at runtime and arrays have to contain objects of same type as opposed to collections.