Last active
January 15, 2024 05:04
-
-
Save davidlhw/d777b73ca65bcd95e12bb02d3d58ea02 to your computer and use it in GitHub Desktop.
The idea is that you will have a generic wrapper `Event<'T>` and then use different types for `'T` to represent different types of Events. These types (referring to `'T`) are never actually instantiated, which is why they're called phantom types.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[<Struct>] | |
type Event<'T> = Event of string | |
type ClickEvent = interface end | |
type KeyEvent = interface end | |
// Now we can create events of different types using the phantom types: | |
let createClickEvent (data: string) : Event<ClickEvent> = Event(data) | |
let createKeyEvent (data: string) : Event<KeyEvent> = Event(data) | |
// The nice thing about this is that we can write functions that work | |
// with any event easily: | |
let logEvent (Event data) = printfn "Event data: %s" data | |
// For example, I can now create one click event, one key event, and | |
// log both: | |
let clickEvent = createClickEvent "Click on button" | |
let keyEvent = createKeyEvent "Press 'Enter' key" | |
logEvent clickEvent | |
logEvent keyEvent | |
// However, trying to mix or compare events of different types will | |
// result in a compile-time error: | |
// This line will not compile because clickEvent and keyEvent have | |
// different phantom types. | |
let result = clickEvent = keyEvent |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment