Skip to content

Instantly share code, notes, and snippets.

@berewt
Last active August 1, 2018 21:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save berewt/1e12e23de3446c22886388ae1069a8a1 to your computer and use it in GitHub Desktop.
Save berewt/1e12e23de3446c22886388ae1069a8a1 to your computer and use it in GitHub Desktop.
module Main
||| The smart consturctor tool:
||| Check whether an element belongs to a given subset
subset : ((x: a) -> Dec (prop x)) -> a -> Either a (Subset a prop)
subset dec y with (dec y)
| (Yes prf) = pure (Element y prf)
| (No contra) = Left y
-- Example
-- Given a simple type Person
record Person where
constructor MkPerson
name : String
age : Nat
-- We want to be able to build a subtype of Person, for adults (18+)
Adult : Nat -> Type
Adult k = Subset Person (LTE k . age)
-- Here is the smart constructor, providing a person, either we can prove that they are more than 18,
-- and we have an Adult, or we can't and we cannot build an Adult value.
adult : Person -> Either Person (Adult 18)
adult = subset (\x => isLTE 18 $ age x)
-- The main difference with another language is that I do not need to hide the
-- Adult consturctor to ensure that my values are correct.
testAdult : Either Person (Adult 18)
testAdult = adult $ MkPerson "me" 38 -- It's a Right (and it's verbose, as I'm a bit old now)
testChild : Either Person (Adult 18)
testChild = adult $ MkPerson "myDaughter" 0 -- Lovely girl, it's a Left.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment