Cannot map an F# discriminated union to an Npgsql enum - f#

I'm attempting to map F# discriminated union to an enum that Npgsql understands. I've used this documentation as reference.
Here's a code sample below:
open Npgsql
open NpgsqlTypes
type Colors =
| Red
| Green
| Blue
NpgsqlConnection.GlobalTypeMapper.MapEnum<Colors>("colors") |> ignore
Unfortunately, I get the following compilation error:
A generic construct requires that the type 'Colors' have a public default constructor
Is there any way to add a default constructor to this discriminated union?

I haven't used Ngpsql, so I don't know if this is the issue, but your Colors union isn't an enum as you have it written. To define an enum in F#, you have to assign an integer to each value, like this:
type Color =
| Red = 0
| Green = 1
| Blue = 2

Related

Nullable anonymous record

Based on a condition, i want to assign either an anonymous record or null to a variable.
For example
let cryptoParameters =
match status with
| Some cryptoParameters ->
{| SecretSalt = cryptoParameters.SecretSalt
PublicIdentityKey = cryptoParameters.PublicIdentityKey
PrivateIdentityKey = cryptoParameters.PrivateIdentityKey |}
| _ -> null
I keep getting the following error:
error FS0043: The type '{| PrivateIdentityKey: string; SecretSalt: string; PublicIdentityKey: string |}' does not have 'null' as a proper value
You can get null values by using Unchecked.defaultof. In the case of an anonymous type. You must provide the whole anonymous definition as an pamarameter like:
let x = Unchecked.defaultof<{|Name:string; Age:int|}>
in your case. The compiler can infer the type, and you can use underscore instead.
let isEven x = x % 2 = 0
let person =
match isEven 3 with
| true -> {Name="David"; Age=100}
| false -> Unchecked.defaultof<_>
But maybe you want to use the Option type instead of using null. That's the way how F# handles null. Because null is usally prohibited by F#.
If you have a problem because Option is a reference type, and it causes some kind of performance problems, then maybe you want to use the ValueOption type instead.
See additionally information on Option like:
Microsoft - Null Values in F#
Microsoft - Options
Microsoft - Value Options
F# for Fun and Profit - The Option Type

Type inference with the same constructor

I am writing a small F# program.
type type_a= | T of int | S of string;;
let aa=T 30;;
type type_b= | T of int | S of string;;
let bb =T 40;;
Above, why how does the compiler distinguish the type for aa and bb? The interactive console from Visual Studio thinks bb is of type type_b, aa is of type type_a.
Both of your discriminated unions are exposing T and S.
When calling let aa=T 30 type_b is not known yet so compiler is infering T from type_a.
On next line type_b is defined and so T and S from type_b are now shadowing T and S from type_a. All subsequent call to T is infered to type_b.
You can still reference T from type_a unsing let cc=type_a.T 50;; in the rest of your code.

How can I use an F# discriminated union type as a TestCase attribute parameter?

I am trying to test that the return result from an F# function matches an expected discriminated union case. I am using NUnit to create the tests and it does not like the discriminated union type as a TestCase parameter. The following test case fails to compile:
[<TestCase("RF000123", Iccm.CallType.Request)>]
let ``callTypeFromCallNumber returns expected call type``
callNumber callType =
test <# Iccm.callTypeFromCallNumber callNumber = callType #>
I expect that this is a limitation of NUnit but I am not completely sure. I have an idea to work around this which I will post as my answer but a more elegant solution will be nice.
How can I use a discriminated union case as a test case attribute parameter?
This isn't a limitation of NUnit, but of the F# language (as well as C# and VB): You can only put constants into attributes, but not objects. Discriminated Unions compile to objects in IL, so you can't put them into attributes.
You can put enums into attributes, though, since they're constants (they're numbers at run-time).
From the example in the OP, it looks like the CallType Discriminated Union has no associated data, so you could consider changing the design to an enum instead:
type CallType =
| Request = 0
| Incident = 1
| ChangeManagement = 2
| Unknown = 3
You should realise, though, that that makes CallType an enum; it's no longer a Discriminated Union. It should enable you to use the values in attributes, though.
Here is my workaround to the problem. It works just fine although I find it a little bit make shift. I just use strings in place of the types and then pattern match to convert to the actual type in the assertion.
[<TestCase("RF000123", "Request")>]
[<TestCase("IM000123", "Incident")>]
[<TestCase("CM000123", "ChangeManagement")>]
[<TestCase("AR000123", "Unknown")>]
let ``callTypeFromCallNumber returns expected call type``
callNumber callType =
test <# Iccm.callTypeFromCallNumber callNumber = match callType with
| "Request" -> Iccm.CallType.Request
| "Incident" -> Iccm.CallType.Incident
| "ChangeManagement" -> Iccm.CallType.ChangeManagement
| _ -> Iccm.CallType.Unknown #>

A very basic Type check fails in F# ... why?

I wrote this code
type Test =
| Age of int
| Name of string;;
let x = Age(10);;
if (x.GetType() = typeof<Test>) then printfn "true" else printfn "false";;
The code prints false. But that puzzles me because isn't Age of type Test?
Also, is there a better way to compare types in F# the .GetType() = typeof<> is very long. I tried :? but I think that's for typecasting rather than comparing types.
The plain answer is, do so:
if (x :> obj) :? Test then printfn "true" else printfn "false"
This issue comes because of the implementation of DUs (using internal classes and tags) and the limitation of F#'s type system (which does not acknowledge the implementation).
As you saw, the type of x is FSI_0001+Test+Age, and F# does not recognize that as a sub-type of Test.
Quoting from the spec
A compiled union type U has:
· One CLI static getter property U.C for each null union case C. This
property gets a singleton object that represents each such case.
· One CLI nested type U.C for each non-null union case C. This type
has instance properties Item1, Item2.... for each field of the union
case, or a single instance property Item if there is only one field.
However, a compiled union type that has only one case does not have a
nested type. Instead, the union type itself plays the role of the case
type.
We see that Age is implemented as a nested type of the parent DU. As a result you could use Type.GetNestedTypes to get all the subtypes of the DU and then test each one to see if the type matches.
But that puzzles me because isn't Test of type Color?
There is no type Color and Test is a type itself so it does not have a type. So your question is nonsensical.
Perhaps you meant to ask why the answer is what it is? If so, it is a consequence of the way F# currently chooses to represent such values internally.

Understanding F# StringConstant

I am trying to understand the following code, particularly StringConstant:
type StringConstant = StringConstant of string * string
[<EntryPoint>]
let main argv =
let x = StringConstant("little", "shack")
printfn "%A" x
0 // return an integer exit code
(By way of context, StringConstant is used in the FParsec tutorial, but this example does not use FParsec.)
What I would like to know is:
what exactly is the type statement doing?
once I instantiate x, how would I access the individual "parts"
("little" or "house")
As others already noted, technically, StringConstant is a discriminated union with just a single case and you can extract the value using pattern matching.
When talking about domain modelling in F#, I like to use another useful analogy. Often, you can start just by saying that some data type is a tuple:
type Person = string * int
This is really easy way to represent data, but the problem is that when you write "Tomas", 42, the compiler does not know that you mean Person, but instead understands it as string * int tuple. One-case discriminated unions are a really nice way to name your tuple:
type Person = Person of string * int
It might be a bit confusing that this is using the name Person twice - first as a type name and second as a name of the case. This has no special meaning - it simply means that the type will have the same name as the case.
Now you can write Person("Tomas", 42) to create a value and it will have a type Person. You can decompose it using match or let, but you can also easily write functions that take Person. For example, to return name, you can write:
let getName (Person(name, _)) =
name
I think single-case discriminated unions are often used mainly because they are really easy to define and really easy to work with. However, I would not use them in code that is exposed as a public API because they are a bit unusual and may be confusing.
PS: Also note that you need to use parentheses when extracting the values:
// Correct. Defines symbols 'name' and 'age'
let (Person(name, age)) = tomas
// Incorrect! Defines a function `Person` that takes a tuple
// (and hides the `Person` case of the discriminated union)
let Person(name, age) = tomas
StringConstant is a discriminated union type, with just a single case (also named StringConstant). You extract the parts via pattern matching, using match/function or even just let, since there is just a single case:
let (StringConstant(firstPart, secondPart)) = x
type StringConstant = StringConstant of string * string
results in a discriminated union with one type.
type StringConstant = | StringConstant of string * string if you execute it in F# interactive.
You can see the msdn documentation on that here.
You can get the value out like this:
let printValue opt =
match opt with
| StringConstant( x, y) -> printfn "%A%A" x y
The other guys already mentioned how you extract the data from a discriminated union, but to elaborate a little more on Discriminated unions one could say that they are sorta like enums on steroids. They are implemented behind the scenes as a type hierarchy where the type is the base class and the cases are subclases of that baseclass with whatever parameter they might have as readonly public variables.
In Scala a similar data-structure is called case classes which might help you convince yourself of this implementationmethod.
One nice property of discriminated unions are that they are self-referenceable and therefor are perfect for defining recursive structures like a tree. Below is a definition of a Hoffman coding tree in just three lines of code. Doing that in C# would probably take somewhere between 5 and 10 times as many lines of code.
type CodeTree =
| Branch of CodeTree * CodeTree * list<char> * int
| Leaf of char * int
For information about Discriminated Unions see the msdn documentation
For an example of using Discriminated Unions as a tree-structure see this gist which is an implementation of a huffman decoder in roughly 60 lines of F#)

Resources