F# new type that is extension of old type - f#

So say I have an employee type
type employee = {
employee_id: int
name: string
department: int
}
type department = {
department_id: int
department_name: string
}
And I want a second type that includes everything in the employee type, but also everything from the department type (in practice the result of an SQL join).
E.g
type employee_extended = {
employee_id: int
name: string
department: int
department_id: int
department_name: string
}
In reality the tables I have have many more columns so just wondering if there was a shorthand to define the extended type :)
Can assume no duplicate of property names, but if it's possible to handle them might be useful in the future.

If you have some data in two types (employee and department) and want to create a new type that contains information about both the employee and the department, the best way is to define a new record type that contains the two other types as fields:
type Employee = {
EmployeeId: int
Name: string
Department: int
}
type Department = {
DepartmentId: int
Department_name: string
}
// New type containing information about
// an employee and also their department
type EmployeeWithDepartment = {
Employee : Employee
Department : Department
}

Related

Prevent class properties to be null when instantiating a Dart class

Assuming I have this Dart class:
class Stock {
int id;
String externalCode;
String internalCode;
String name;
double quantity;
}
When I create a new instance of this object like Stock item = new Stock(); all the properties are null.
I know this is a Dart specific behavior, but when sending such objects to an API, since most backend languages like C#, Java etc. don't have nullable primitives exceptions occur when parsing to a corresponding model class.
What is the simplest approach to prevent int, double and bool properties of being null (set them to 0, 0.0 and false respectively) when instantiating a Dart class?
Since many classes might have a lot of properties, a hardwired instantiation like Stock item = new Stock(id: 0, quantity: 0 /*...and so on... */); it's out of the question.
Many thanks!
If you want a default value for members in a class you can just assign each member to a value in the class definition:
class Stock {
int id = 0;
String externalCode = "";
String internalCode = "";
String name = "";
double quantity = 0.0;
}
Alternative, you can also give default values to optional parameters like:
class Stock {
int id;
String externalCode;
String internalCode;
String name;
double quantity;
Stock(
{this.id = 0,
this.externalCode = '',
this.internalCode = '',
this.name = '',
this.quantity = 0.0});
}

Some mistakes in the language

I'm new in Dart, I want to precise this. I create two classes in Dart, one is 'Person' and the other one is a child of the first one, and it's named 'Employee'.
I create an object of Person. When I change this object to an Instance of class Employee, nothing wrong. But at the time that I'm asking to a parameter that is inside the Employee, I raised an error.
So why Dart allow me to the class of the object, but not allowed me to access to a parameter inside the new class?
The code below :
void main {
var person = Person(name: "Zozor");
print(person.describe());
person = Employee(taxCode: 'AAB');
person.sayName();
print(person.taxCode);
}
class Person {
Person({this.name, this.age, this.height});
String name;
final int age;
final double height;
String describe() => "Hello, I'm ${this.name}. I'm ${this.age} and I'm ${this.height} meter${this.height == 1 ? '':'s'} tall";
void sayName()=> print("Hello, I'm ${this.name}.");
}
class Employee extends Person {
Employee({String name, int age, double height, this.taxCode, this.salary}) : super(name:name, age: age, height: height);
final String taxCode;
final int salary;
}
Variables in Dart must be declared before being used. They have a type and store a reference to the value (see https://www.tutorialspoint.com/dart_programming/dart_programming_variables.htm).
var person = Person(name: "Zozor");
Declares the variable person of type Person (type is derived from the type of class it is initialized to).
When you assign:
person = Employee(taxCode: 'AAB');
The type is unchanged with the assignment (i.e. remains Person), only the reference changes to the result of downcasting the Employee to a Person (the downcasting is done implicitly as described https://news.dartlang.org/2012/05/types-and-casting-in-dart.html).
The above is due to var creating static type variables.
An alternative would be to use dynamic typing as in:
dynamic person = Person(name: "Zozor");
This declares a person variables whose type is dynamic. Now when the assignment is made to Employee:
person = Employee(taxCode: 'AAB');
The type of the person variable is now Employee rather than Person. Furthermore, there is no downcasting of Employee and no error message related to taxCode.
A simple way to stay with static (rather than using dynamic) is to use an explicit recasting of person to Employee:
print((person as Employee).taxCode);
This casts a person to Employee then gets the taxCode.

Writing to mutable property for a struct record is not allowed in F#. Why?

When I have the following code:
[<Struct>]
type Person = { mutable FirstName:string ; LastName : string}
let john = { FirstName = "John"; LastName = "Connor"}
john.FirstName <- "Sarah";
The compiler complains that "A value must be mutable in order to mutate the contents". However when I remove the Struct attribute it works fine. Why is that so ?
This protects you from a gotcha that used to plague the C# world a few years back: structs are passed by value.
Note that the red squiggly (if you're in IDE) appears not under FirstName, but under john. The compiler complains not about changing the value of john.FirstName, but about changing the value of john itself.
With non-structs, there is an important distinction between the reference and the referenced object:
Both the reference and the object itself can be mutable. So that you can either mutate the reference (i.e. make it point to a different object), or you can mutate the object (i.e. change the contents of its fields).
With structs, however, this distinction does not exist, because there is no reference:
This means that when you mutate john.FirstName, you also mutate john itself. They are one and the same.
Therefore, in order to perform this mutation, you need to declare john itself as mutable too:
[<Struct>]
type Person = { mutable FirstName:string ; LastName : string}
let mutable john = { FirstName = "John"; LastName = "Connor"}
john.FirstName <- "Sarah" // <-- works fine now
For further illustration, try this in C#:
struct Person
{
public string FirstName;
public string LastName;
}
class SomeClass
{
public Person Person { get; } = new Person { FirstName = "John", LastName = "Smith" };
}
class Program
{
static void Main( string[] args )
{
var c = new SomeClass();
c.Person.FirstName = "Jack";
}
}
The IDE will helpfully underline c.Person and tell you that you "Cannot modify the return value of 'SomeClass.Person' because it is not a variable".
Why is that? Every time you write c.Person, that is translated into calling the property getter, which is just like another method that returns you a Person. But because Person is passed by value, that returned Person is going to be a different Person every time. The getter cannot return you references to the same object, because there can be no references to a struct. And therefore, any changes you make to this returned value will not be reflected in the original Person that lives inside SomeClass.
Before this helpful compiler error existed, a lot of people would do this:
c.Person.FirstName = "Jack"; // Why the F doesn't it change? Must be compiler bug!
I clearly remember answering this question almost daily. Those were the days! :-)

Grails "duplicate field name" error in static mapping closure

I am receiving the following errors in my "Class" class in Grails. For each field, it is telling me that I have a duplicate field. Which doesn't make any sense, because all I'm trying to do is map the fields with their associated table columns. The class fields and the fields in my mapping closure are all underlined. Here is my class so far:
package booklist
class Class {
Integer id
String name
String description
String instructor
String courseNumber
String lineNumber
List books
BigDecimal bookTotalPrice
String sequenceNumber
String subjectCode
static constraints = {
}
static mapping = {
//Uses the default datasource
table ''
columns {
id column: 'class_id'
name column: 'class_name'
description column: 'course_description'
instructor column: 'instructor_name'
courseNumber column: 'course_number'
lineNumber column: 'line_number'
bookTotalPrice column: 'book_total_price'
sequenceNumber column: 'sequence_number'
subjectCode column: 'subject_code'
}
}
}
You don't need to declared in static mapping the fields that you don't need to rename. Just write this:
package booklist
class MyClass {
Integer id
String name
String description
String instructor
String courseNumber
String lineNumber
List books
BigDecimal bookTotalPrice
String sequenceNumber
String subjectCode
static mapping = {
description column: 'course_description'
}
}
Grails works with the CoC (Convention Over Configuration) approach: if you don't need to change something, don't write it and a convention will be used.
For more details about the column mapping, take a look at the Grails documentation: http://grails.org/doc/latest/ref/Database%20Mapping/column.html

Grails Scaffolding - define possible values for this property of a domain class

I am new to Grails. I have a Person domain class as :
class Person {
String firstName
String lastName
String gender
Date dateOfBirth
}
And wondering if I can define possible values for a property - say gender as {M, F, U} so that these three values will be listed in combo box when using dynamic scaffolding for Person controller.
Here I just wanted to know if there is such feature in Grails framework? If such feature exists , then how can I use it?
From the documentation http://grails.org/doc/latest/guide/scaffolding.html, you should be able to use an inList constraint:
class Person {
String firstName
String lastName
String gender
Date dateOfBirth
def constraints = {
gender( inList: ["M", "F", "U"])
}
}
This should scaffold to a select list for the gender field, depending on the version of Grails you're using. 2.0+ definitely does this.
Here is an alternative solution
class Person {
String firstName
String lastName
enum Gender {
M(1),
F(2),
U(3)
private Gender(int val) { this.id = val }
final int id
}
Gender gender = Gender.U
Date dateOfBirth
def constraints = {
gender()
}
}
This will store gender in the database as an integer (1,2,3) and default the gender to U. The benefit here is you can rename what F, M, and U mean without handling a data migration.

Resources