Create collection of type - f#

I created a record type
type IpRanges = {ipStart: IPAddress; ipEnd: IPAddress; subnet: IPAddress; mask: IPAddress}
How can I create a collection type of IpRanges?
type CollRanges = ???

What kind of collection do you want to create?
A list of IPRanges? If so you can do it like this:
type CollRanges = List<IpRanges>
But since list is generic your CollRanges doesn't really need to be a new type, indeed the previous line will create a type alias which is a good thing since you will reuse all the functionality of the List type and your collection will be more cohesive (plugabble) with existing F# code. The same applies to any other generic collection, like Array, Seq, ResizeArray, ...

Related

Defining element type in a table

so when i define the type of a variable, it goes totally alright:
local Player: Player = nil
but when i try to define the type of an element in a table, it doesnt go exactly how i thought it would:
PlayerProfile.Player: Player = nil
Missed symbol `(`.Luau Syntax Check.(miss-symbol)
this is my first time working with type so anyone know the correct way of doing this?
You can't arbitrary set type to random table member in Luau. You need to set types for all members on table creation or inside its creation scope.
On creation you can simply set type for each field directly:
type PlayerProfile = {Player: SomeType, OtherField: SomeOtherType}
Or you can express member types by first creating table with zero expression {} and assigning typed values to its members before leaving creation scope. But as soon as you leave that scope the table is "sealed" and no more changes are allowed.
local PlayerProfile = {}
PlayerProfile.Player = "string"
PlayerProfile.SomeField = 123 -- number, types are inferred from initialization values

How to derive record types in F#?

I'm inserting data into Azure CosmosDB via FSharp.ComosDb. Here is the record type that I write in the DB:
[<CLIMutable>]
type DbType =
{ id: Guid
Question: string
Answer: int }
The persistence layer works fine but I face an inelegant redundancy. The record I'm inserting originates from the Data Transfer Object (DTO) with the following shape:
type DataType =
{ QuestionId: Guid
Question: string
Answer: int }
CosmosDb accepts only records with a lowercase id. Is there any way to derive the DbType from DataType or I have to define DbType from scratch?
Is there anything a la copy and update record expression record2 = { record1 with id = record1.QuestionId } but at the type level?
There's no type-level way of deriving one record type from another the way you describe, you can however get reasonably close with the addition of anonymous records in F# 4.6.
type DataType =
{ QuestionId: Guid
Question: string
Answer: int }
let example =
{ QuestionId = Guid.NewGuid()
Question = "The meaning of life etc."
Answer = 42 }
let extended =
{| example with id = example.QuestionId |}
This gives you a value of an anonymous record type with an added field, and may be well suited to your scenario, however it's unwieldy to write code against such type once it leaves the scope of the function you create it in.
If all you care is how this single field is named - serialization libraries usually have ways of providing aliases for field names (like Newtonsoft.Json's JsonProperty attribute). Note that this might be obscured from you by the CosmosDb library you're using, which I'm not familiar with.
Another more involved approach is to use generic envelope types so that the records you persist have a uniform data store specific header across your application:
type Envelope<'record> =
{
id: string
// <other fields as needed>
payload: 'record
}
In that case the envelope contains the fields that your datastore expects to be there to fulfill the contract (+ any application specific metadata you might find useful, like timestamps, event types, versions, whatnot) and spares you the effort of defining data store specific versions of each type you want to persist.
Note that it is still a good idea in general to decouple the internal domain types from the representation you use for storage for maintainability reasons.

F# Turning XmlProvider data into Records

I am pulling in some XML data using XmlProvider, and I will be accessing it from C#. As you can't use type provided fields directly from C#, I need create record out of them. I can do this by hand but I believe this should be possible to automate using reflection. If I create record types with the same names and types as the fields in the type provider, I should be able to use something like FSharpValue.MakeRecord(typeof<MyType>,values) where values is an array of objects.
What I don't know is how to get the array of values out of the type provider, and how to handle nested records, for instance:
type Address =
{
Address1 : string
City : string
State : string
}
type Client =
{
Id : int
FullName : string
Address : Address
}
In this case Client contains one Address. Will I need to walk the tree and use MakeRecord on the leaves and work my way up?
If you're willing to hand code the types, why do you need the type provider in the first place?
If you're doing some additional logic on F# side, you'll have no choice but to create the records manually anyway. And if you're not doing anything, you can just use the .NET out of the box serializer (or another library) to create them from xml.

Determine Data Type

I have this code in my controller:
def cols = grailsApplication.getDomainClass('com.archie.Build').persistentProperties.collect {it.name}
The code above will allow me to list all the property names I have in Build class. Now, I would like to include also the properties data type, ie. boolean, String etc...
Somewhat like the output is:
[floorType:String, floorWidth:Float, ......]
Maybe not exactly like that, or maybe similar, but as long as I can return their data type. Can someone help? Thank you.
Each entry in persistentProperties is a GrailsDomainClassProperty, and this provides access to the type of the property as a Class object:
def props = [:]
grailsApplication.getDomainClass('com.archie.Build'
).persistentProperties.each {
props[it.name] = it.type.name
}
Or just pass the persistentProperties array itself through to the GSP, then extract .name and .type there.
You may also wish to consider using constrainedProperties instead of/in addition to the persistentProperties. The constrainedProperties map lists only those properties that are mentioned in the domain class constraints block, but the iterator over this map is guaranteed to return the properties in the order they are listed in the constraints. This is how the default scaffolding operates, as I'm not aware of any way to control the order of the persistentProperties array.

Map of other types than Strings in Grails

I created simple domain class with map within it.
class Foo {
Map bar
}
Bar mapping will be created as sth like:
create table foo_bar (bar bigint, bar_idx varchar(255),
bar_elt varchar(255) not null);
...as stated in http://www.grails.org/GORM+-+Collection+Types:
The static hasMany property defines
the type of the elements within the
Map. The keys for the map MUST be
strings.
Now my question is - is it possible to create map of values other than Strings? I can achieve that using pure Hibernate (element mapping) - any ideas how to port this to Grails?
I think you meant if it's possible to create map of KEYS other than Strings.
It is not possible: all keys must be Strings, while values can be whatever type you want.
A way to achieve what you want is using some unique identifier for the type of class you want as key of your map.
Say you want a Map persisted in your database and say you have two instances: objectA and objectB you want to persist in your map, which name is "relationship":
relationship."objectA.toString()" = objectB
That should work. Changet toString() with hashCode(), getId() or whatever thing that gives you a unique String that identifies that object and only that, and you got it.

Resources