Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# discriminated unions versus 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 it 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 )

??

like image 498
Hugo Avatar asked Sep 07 '11 12:09

Hugo


2 Answers

F# discriminated unions correspond to OO class hierarchies quite closely, so this is probably the best option. The most notable difference is that you cannot add new cases to a discriminated union without modifying 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 don't expect to add new inherited classes (cases), then this is the best option. Otherwise, you may use F# object types (or other options, depending on the scenario).

One more point regarding your code - since you cannot add new cases, F# compiler knows that the only cases you need are for B and C. As a result, the block_3 can never be executed, which means that you can write just:

let my_fct x = 
  match x with 
  | B -> ( block_1 ) 
  | C -> ( block_2 ) 
like image 181
Tomas Petricek Avatar answered Nov 03 '22 08:11

Tomas Petricek


yes this is more or less the same as F# does anyhow. In this case (no values added) - F# seems to translate this into a classs for "a" and some Tags (enumeration). The class for "a" just has some static properties for B and C, and some methods to check if an object of type "a" is "B" or "C" (see below)

Object-Browser of the types

But you don't need the "_ -> (block_3)" case, because this can never be matched (F# knows all the possible cases and will warn you).

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

like image 37
Random Dev Avatar answered Nov 03 '22 08:11

Random Dev