7 people like it.
Like the snippet!
Phantom type example
The snippet shows a minimal example of phantom types for type-safe way of tracking different types of IDs in a simple system.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
|
// The idea is that you will have a generic wrapper ID<'T> and then use
// different types for 'T to represent different types of IDs. Those types
// are never actually instantiated, which is why they're called phantom types.
[<Struct>]
type ID<'T> = ID of System.Guid
type CustomerID = interface end
type ProductID = interface end
// Now you can create ID<CustomerID> and
// ID<ProductID> values to represent two kinds of IDs:
let newCustomerID () : ID<CustomerID> = ID(System.Guid.NewGuid())
let newProductID () : ID<ProductID> = ID(System.Guid.NewGuid())
// The nice thing about this is that you can write functions that work with any ID easily:
let printID (ID g) = printfn "%s" (g.ToString())
// For example, I can now create one customer ID, one product ID and print
// both, but I cannot do equality test on those IDs, because they're types do not match:
let ci = newCustomerID ()
let pi = newProductID ()
printID ci
printID pi
ci = pi
|
Multiple items
type StructAttribute =
inherit Attribute
new : unit -> StructAttribute
Full name: Microsoft.FSharp.Core.StructAttribute
--------------------
new : unit -> StructAttribute
namespace System
Multiple items
type Guid =
struct
new : b:byte[] -> Guid + 4 overloads
member CompareTo : value:obj -> int + 1 overload
member Equals : o:obj -> bool + 1 overload
member GetHashCode : unit -> int
member ToByteArray : unit -> byte[]
member ToString : unit -> string + 2 overloads
static val Empty : Guid
static member NewGuid : unit -> Guid
static member Parse : input:string -> Guid
static member ParseExact : input:string * format:string -> Guid
...
end
Full name: System.Guid
--------------------
System.Guid()
System.Guid(b: byte []) : unit
System.Guid(g: string) : unit
System.Guid(a: int, b: int16, c: int16, d: byte []) : unit
System.Guid(a: uint32, b: uint16, c: uint16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : unit
System.Guid(a: int, b: int16, c: int16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : unit
type CustomerID
Full name: Script.CustomerID
type ProductID
Full name: Script.ProductID
val newCustomerID : unit -> 'a
Full name: Script.newCustomerID
System.Guid.NewGuid() : System.Guid
val newProductID : unit -> 'a
Full name: Script.newProductID
val printID : 'a -> 'b
Full name: Script.printID
val _arg1 : 'a
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val ci : obj
Full name: Script.ci
val pi : obj
Full name: Script.pi
More information