Reputation: 201
I'm trying to add F# project to my C# solution. I created a F# project and wrote some F# code, now I'm trying to use it from my C# projects. I successfully referenced F# project and can access it's types, but having issues with discriminated unions. For example I have following types defined in F#:
namespace Sample
type NotificationReceiverUser = NotificationReceiverUser of string
type NotificationReceiverGroup = NotificationReceiverGroup of string
type NotificationReceiver = NotificationReceiverUser | NotificatonReceiverGroup
I can create NotificationReceiverUser object directly as follows:
var receiver = NotificationReceiverUser.NewNotificationReceiverUser("abc");
,but I need NotificationReceiver object, and I'm not getting NotificationReceiver.NewNotificationReceiverUser or NotificationReceiver.NewNotificationReceiverGroup static methods. Looking at some other SO questions it looks like these methods should be available by default. Would appreciate any pointers on why they are missing for me.
Upvotes: 2
Views: 1286
Reputation: 80724
What you're trying to do is not a "discriminated union". It's an indiscrimnated union. First you created two types, and then you're trying to say: "values of this third type may be either this or that". Some languages have indiscriminated unions (e.g. TypeScript), but F# does not.
In F#, you can't just say "either this or that, go figure it out". You need to give each case of the union a "tag". Something by which to recognize it. That's why it's called a "discriminated" union - because you can discriminate between the cases.
For example:
type T = A of string | B of int
Values of type T
may be either string
or int
, and the way to know which one is to look at the "tags" assigned to them - A
or B
respectively.
The following, on the other hand, is illegal in F#:
type T = string | int
Coming back to your code, in order to "fix" it the mechanical way, all you need to do is add case discriminators:
type NotificationReceiverUser = NotificationReceiverUser of string
type NotificationReceiverGroup = NotificationReceiverGroup of string
type NotificationReceiver = A of NotificationReceiverUser | B of NotificatonReceiverGroup
But my intuition tells me that what you actually meant to do was this:
type NotificationReceiver =
| NotificationReceiverUser of string
| NotificatonReceiverGroup of string
Two cases of the same type (weird, but legal), still distinguished by tags.
With such definition, you would access it from C# thusly:
var receiver = NotificationReceiver.NewNotificationReceiverUser("abc");
Upvotes: 5