Skip to content

Instantly share code, notes, and snippets.

@ganwell
Last active December 16, 2018 18:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ganwell/30a445fe02afcbbbb8b220546140e1b4 to your computer and use it in GitHub Desktop.
Save ganwell/30a445fe02afcbbbb8b220546140e1b4 to your computer and use it in GitHub Desktop.
Move exceptions to compiler errors?
(* I am a newbie and its quite probable that I am trying to achieve something
* unnecessary or otherwise wrong.
*
* I have a program written in a dynamically typed language, where I have a lot
* assert_X_consistency functions that will run after every state change, so any
* inconsistency I thought of, will raise an exception. I heard that a good type
* system allows you to encode the state in a way that doesn't allow the
* inconsistencies at compile-time.
*
* What I am trying to move to the compiler is: 'assert a is in team0'
*
* By selecting player1 for 'a' I have chosen team1 and this is known at
* compile-time, if by accident I pass it to a function that expects team0 I
* want a compiler-error.
*
* I know the code below is stupid, but my more elaborate ways to encode the
* state, will confuse what I am trying to achieve.
*
* For example I can use an option (Some / None), but in the end this is also a
* runtime-error, not a compiler-error. Is it even possible/useful to get a
* compiler-error?
*
* *)
(* Teams and players *)
type team0 = Player0 | Player2
type team1 = Player1 | Player3
type player = Team0 of team0 | Team1 of team1
(* Player shortcuts *)
let player0 = Team0 Player0
let player1 = Team1 Player1
let player2 = Team0 Player2
let player3 = Team1 Player3
(* This gives a warning *)
(* Warning 8: this pattern-matching is not exhaustive. *)
let get_team0 p = match p with Team0 t0 -> t0
(* Tests *)
let a = player1
(* But I want this to be a compiler error *)
(* Exception: Match_failure ("jazz.ml", 58, 18). *)
let (b : team0) = get_team0 a
(* Or rather something like let (b : team0) = a *)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment