Skip to content

Instantly share code, notes, and snippets.

@schuelermine
Created January 11, 2022 19:17
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 schuelermine/6a06efcc0c5b3a18768c4649e4cc8efb to your computer and use it in GitHub Desktop.
Save schuelermine/6a06efcc0c5b3a18768c4649e4cc8efb to your computer and use it in GitHub Desktop.
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, TypeApplication, ExplicitNamespaces, AllowAmbiguousTypes, StandaloneDeriving #-}
import Data.Either
-- @ Control/TypeAssert.hs
{- module Control.TypeAssert where -}
class Assert t n y | n -> t, y -> t where
assert :: t -> Either n y
clearL :: n -> t
clearR :: y -> t
check :: t -> Bool
{-# MINIMAL assert, clearL, clearR #-}
check = isRight . assert @t @n @y
-- @ Control/TypeAssert/EvenOdd.hs
{- module Control.TypeAssert.EvenOdd (type Even, type Odd) where -}
newtype Odd n = Odd n
newtype Even n = Even n
deriving instance Show n => Show (Odd n)
deriving instance Show n => Show (Even n)
instance Integral n => Assert n (Odd n) (Even n) where
assert n | even n = Right $ Even n
| otherwise = Left $ Odd n
clearL (Odd n) = n
clearR (Even n) = n
check = even
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment