F # discriminatory unions compared to C # class hierarchies

I have the following code:

public abstract class A ... public class B : A ... public class C : A ... void my_fct(A x) { if (x is B) { block_1 } else if (x is C) { block_2 } else { block_3 } } 

and I wonder if this is a good translation from F #

 type a = B | C let my_fct x = match x with | B -> ( block_1 ) | C -> ( block_2 ) | _ -> ( block_3 ) 

??

+6
source share
2 answers

F # discriminatory unions correspond to OO class hierarchies pretty closely, so this is probably the best option. The most noticeable difference is that you cannot add new cases to a discriminatory union without changing the type declaration. On the other hand, you can easily add new functions that work with the type (which roughly corresponds to adding new virtual methods in C #).

So, if you do not expect to add new inherited classes (cases), then this is the best option. Otherwise, you can use F # object types (or other parameters, depending on the scenario).

Another point related to your code is that since you cannot add new cases, the F # compiler knows that the only cases you need are B and C As a result, block_3 never be executed, which means you can simply write:

 let my_fct x = match x with | B -> ( block_1 ) | C -> ( block_2 ) 
+11
source

yes, this is more or less the same as F #. In this case (without added values) - F # seems to translate this into classes for "a" and some tags (enumeration). The class for β€œa” simply has some static properties for B and C and some methods for checking whether an object of type β€œa” is β€œB” or β€œC” (see below)

Object-Browser of the types

But you do not need the case "_ β†’ (block_3)", because it can never be matched (F # knows all the possible cases and warns you).

I think it is better if you throw an exception in C # for this "else" case.

+7
source

Source: https://habr.com/ru/post/896784/


All Articles