maps as anonymous struct members - dictionary

I was stumbling over some behavior in go which I cannot make sense of completely and explainations of any kind would be wellcome:
type Test struct{
Name string // or other metadata to be stored along the core map element
map[string]string
}
The above code will fail to compile with an unexpected map error.
Which is probably because struct Field delarations must be types, however I fail to appriciate why map[string]string is not a type.
Changing it to
type Embedded map[string]string
type Test struct{
Name string
Embedded
}
get's arround the compiler error, but still Test["someKey"] raises the compiler error
invalid operation: Test["someKey"] (index of type Test).
Of course adressing the anoymous field directly with Test.Embedded["someKey"] works,
but my questions are:
Why are literal map declarations valid as types in non-anonymous field declarations but not valid in anonymous fields
Why does indexing the containing type not work? Why can't it work?
Thanks for clarifications.

Anonymous fields must be named types only. You're perhaps somewhat confusing Type, LiteralType and TypeName.
Referring to an anonymous field is presribed by the specs to be done always by its type name. Thus Test.Embedded[key] is the only legal form. Here you might be confusing the embedded field methods, which are inherited from embedded fields w/o need to use the field name and the field value, which must use it.

Related

Passing string list to F# asp.Net api

I actually solved my problem before posting, but I wonder if there are any better solutions?
Also if there is somewhere where there is a way to use list as-is?
I am writing a simple get endpoint if F# which needs to accept a list of strings as an argument.
I take that list as the input to a query that runs as expected, I am not worried about that part.
The problem I am facing is as follows (minimal implmenetation):
When I define the endpoint as:
[<HttpGet>]
member _.Get() =
processStrings [ "test"; "test2" ]
it returns as expected.
When I change it to:
[<HttpGet>]
member _.Get([<FromQuery>] stringList: string list) = processStrings stringList
I get an error:
InvalidOperationException: Could not create an instance of type 'Microsoft.FSharp.Collections.FSharpList`1[[System.String, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Record types must have a single primary constructor. Alternatively, give the 'stringList' parameter a non-null default value.
Which doesn't make much sense to me, as I am using a list of strings, which in C# at least defaults to an empty list.
So I assume this comes down to how C# and F# interpret these signatures, but I am not sure how to resolve it.
I tried this signature and received the same error as above....
member _.Get( [<Optional; DefaultParameterValue([||]); FromQuery>] stringList: string list) = processStrings stringList
In the end using the following did solve the problem.
member _.Get( [<Optional; DefaultParameterValue([||]); FromQuery>] stringList: string seq) = processStrings stringList
I assume it was solved because seq is just IEnumerable, and then presumable list isn't just List from C# (mutable vs immutable). But is there a way to use an F# list in [FromQuery] parameters? Would [FromBody] have just worked? (No is the tested answer) Is there a way to add a type provider for an endpoint like this?
Is there something else I am missing here? Mine works now, but I am curious to the implications of the above.
I have not tested this, but I would assume that ASP.NET does not support F# lists as arguments. I would guess that taking the argument as an array would be much more likely to work:
[<HttpGet>]
member _.Get([<FromQuery>] stringList: string[]) =
processStrings (List.ofArray stringList)

Graphql Schema doku displays Input type automatically with Input

I have added leangen/graphql-spqr as described in the readme.
Before we had a custom implementation of graphql types like in customtype.types.gql.
After implementation, everything works fine, except the type which are called e.g. OperatorInput, are named in the autogenerated graphql doc like "OperatorInputInput".
I tried to Change it like this in the declaration:
#GraphQLArgument(name = "OperatorInput", description = "Required fields for Operator") OperatorInput operator
But it wasn't applied.
Do you know any workaround?
This is intended. Keep in mind that in GraphQL's type system, input and output types are strictly different. Let's say you have this in Java:
public Book saveBook(Book in) {...}
The Book that is the return type and the Book that is the argument type are 2 different types in GraphQL, and must have unique names. So Input is added automatically to make the names unique.
If you're 100% sure you want to override this, register a custom TypeInfoGenerator via GraphQLSchemaGenerator#withTypeInfoGenerator. You can inherit from DefaultTypeInfoGenerator and override generateInputTypeName. BUT! Do pay attention that if you end up producing the same name for 2 different types, all hell breaks loose. So maybe only drop the suffix Input if the classname already ends with Input and never ever use such classes for output.
Btw #GraphQLArgument sets the name of the argument, not the name of the type of the argument.

Complex type checks in XQuery

I have a schema that has many complexType, some of which have subtypes (via xsi:type). I need to create an XQuery expression that checks that an element (MyPath) is a member of a parent type, but no others, I've tried an expression in the form below with no luck.
/MyPath[element(*,ParentClass) and not element(*,ChildClass)]
It appears element applies to all the children in the context it is called, but not itself (MyPath), which yields no results.
I also tried the instance of operator, but this appears to only work for simpleType.
You should use
. instance of element(*, ParentClass)
and not(. instance of element(*, ChildClass))
If this doesn't work please supply an MCVE
An alternative, using Saxon extension functions, is to test the type annotation directly: saxon:type-annotation(.) eq xs:QName('ParentClass')
Of course, there's a question about whether this is good practice. The whole point of defining a derived type is that it is supposed to be substitutable for the base type; everywhere you can use an instance of the parent type, you should be able to substitute an instance of the child type. You appear to be deliberately trying to contrive a query in which this is not the case.

How does golang implement reflection?

Using reflection, we can get the type name, storage size and the function of the given type(such as uint64, user-defined struct and so on). Even, we can modify some fields of the given type.
How does golang implement reflections? I guess the following ways:
Every type in golang, including user-defined type, itself has the information about type name, fields name and the function name. Golang reflection just reads these information or call the function.
Through some mechanism, Golang can get the type name, storage size and so on. And the type itself doesn’t have these information.
I have read the golang reflection code roughly. I guessed that golang used the second way.
Who can describe the concrete implement of reflection? Or recommend me some documents? Reading all code is difficult for me.
This is just an overview and it might be not 100% accurate but hopefully you will find it helpful.
At build time Go linker will embed information about all types used by the application into the executable (https://github.com/golang/go/blob/master/src/runtime/symtab.go#L39)
Each interface value contains a pointer to the data type descriptor (https://github.com/golang/go/blob/master/src/runtime/type.go#L14)
During conversion from a type that is known at compile time to an interface value Go compiler will point type descriptor of this interface value to the concrete type descriptor (it is known at compile time!).
E.g. when you call reflect.TypeOf(uint(87)):
an interface value is created by the compiler that references uint type descriptor
this interface value is passed to reflect.TypeOf function as argument
reflect.TypeOf function uses type descriptor that has been stored by the linker in the executable to get the align (and other) information about uint type.
The description of interfaces is well described here: The Laws of Reflection.
A variable of interface type stores a pair: the concrete value
assigned to the variable, and that value's type descriptor.
Basically, type are known statically from your code. More flexible interface types keep the original underlying type for getting back to the original data type.

How do I get the PropertyInfo.PropertyType name of a EntityReference type via reflection

I am writing a small code generator which would read into an edmx file and create business objects on the base of a template. I am using reflection to spit out the type names.
The problem is when I encounter a property (PropertyInfo) of type Entity Reference, (basically an entity property if there is a referential integrity), the PropertyInfo.PropertyType.Name comes as "EntityReference`1" which is not recognized by the compiler.
PropertyInfo.PropertyType.FullName gives "System.Data.Objects.DataClasses.EntityReference`1[[BusinessObjectGenerator.Models.BE_Additional_Info, BusinessObjectGenerator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]", which is also not recognized by the C# compiler.
Now I faced the same problem with the Nullable types. And I found the static method Nullable.GetUnderlyingType(type) which solved the issue. How do I get the name of type of a property that is an entity type, a name that the C# compiler recognizes?
Generic types contain ` in their Name. To get the C# readable name of the type, you will need to first check if it is a generic type using Type.IsGenericType. If it is a generic type, then you can use Type.GetGenericArguments() to get the list of type arguments to the generic type. By getting their names, you can put together the generic type name like. For example, if the type is
Dictionary<int, string>
Then, the type name would actually be Dictionary`2. Using GetGenericArguments would return an array with two types (int, and string). From these you can generate the composite name.
Note: Each of the types returned from GetGenericArguments() may itself be a generic type, so you should write this as a recursive algorithm.

Resources