Reputation: 33
I wonder if they are simply using a number to represent each cases, or they will be compiled to control flows (if statements) that helps decide the matter
pure means the cases aren't of any data types
I tried looking for answers on stack overflow but I didn't find any
Upvotes: 0
Views: 176
Reputation: 1558
In general yes, each case is a number (called Tag in the implementation). It's easy to figure out how some things are realized in F# by decompiling F# assembly to C#.
E.g.
Union type defined like this:
type UnionType = This | That of int
Decompiles to C# like this (I cut out interface implementations at the bottom as it is pretty lengthy, you can easily repeat this process yourself):
[Serializable]
[StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto)]
[DebuggerDisplay("{__DebugDisplay(),nq}")]
[CompilationMapping(SourceConstructFlags.SumType)]
public abstract class UnionType : IEquatable<UnionType>, IStructuralEquatable, IComparable<UnionType>, IComparable, IStructuralComparable
{
public static class Tags
{
public const int This = 0;
public const int That = 1;
}
[Serializable]
[SpecialName]
[DebuggerTypeProxy(typeof(_This@DebugTypeProxy))]
[DebuggerDisplay("{__DebugDisplay(),nq}")]
internal class _This : UnionType
{
[CompilerGenerated]
[DebuggerNonUserCode]
internal _This()
{
}
}
[Serializable]
[SpecialName]
[DebuggerTypeProxy(typeof(That@DebugTypeProxy))]
[DebuggerDisplay("{__DebugDisplay(),nq}")]
public class That : UnionType
{
[DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
[CompilerGenerated]
[DebuggerNonUserCode]
internal readonly int item;
[CompilationMapping(SourceConstructFlags.Field, 1, 0)]
[CompilerGenerated]
[DebuggerNonUserCode]
public int Item
{
[CompilerGenerated]
[DebuggerNonUserCode]
get
{
return item;
}
}
[CompilerGenerated]
[DebuggerNonUserCode]
internal That(int item)
{
this.item = item;
}
}
[SpecialName]
internal class _This@DebugTypeProxy
{
[DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
[CompilerGenerated]
[DebuggerNonUserCode]
internal _This _obj;
[CompilerGenerated]
[DebuggerNonUserCode]
public _This@DebugTypeProxy(_This obj)
{
_obj = obj;
}
}
[SpecialName]
internal class That@DebugTypeProxy
{
[DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
[CompilerGenerated]
[DebuggerNonUserCode]
internal That _obj;
[CompilationMapping(SourceConstructFlags.Field, 1, 0)]
[CompilerGenerated]
[DebuggerNonUserCode]
public int Item
{
[CompilerGenerated]
[DebuggerNonUserCode]
get
{
return _obj.item;
}
}
[CompilerGenerated]
[DebuggerNonUserCode]
public That@DebugTypeProxy(That obj)
{
_obj = obj;
}
}
[DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
[CompilerGenerated]
[DebuggerNonUserCode]
internal static readonly UnionType _unique_This = new _This();
[CompilerGenerated]
[DebuggerNonUserCode]
[DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
public int Tag
{
[CompilerGenerated]
[DebuggerNonUserCode]
get
{
return (this is That) ? 1 : 0;
}
}
[CompilerGenerated]
[DebuggerNonUserCode]
[DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
public static UnionType This
{
[CompilationMapping(SourceConstructFlags.UnionCase, 0)]
get
{
return _unique_This;
}
}
[CompilerGenerated]
[DebuggerNonUserCode]
[DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
public bool IsThis
{
[CompilerGenerated]
[DebuggerNonUserCode]
get
{
return this is _This;
}
}
[CompilerGenerated]
[DebuggerNonUserCode]
[DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
public bool IsThat
{
[CompilerGenerated]
[DebuggerNonUserCode]
get
{
return this is That;
}
}
[CompilerGenerated]
[DebuggerNonUserCode]
internal UnionType()
{
}
[CompilationMapping(SourceConstructFlags.UnionCase, 1)]
public static UnionType NewThat(int item)
{
return new That(item);
}
/* cut out members including interface implementations */
}
Upvotes: 1