{-# LANGUAGE UnicodeSyntax #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE MultiParamTypeClasses #-} -- | Type-indexed runtime-checked properties. module Data.Checked ( Checked , trustMe , checked , Property(..) , maybeHolds , check ) where -- | Wrapper-evidence for property /p/. newtype Checked p v = Checked v -- | Use when the property can be deduced without a runtime check. trustMe ∷ v → Checked p v trustMe = Checked {-# INLINE trustMe #-} -- | Unwrap the checked value. checked ∷ Checked p v → v checked (Checked v) = v {-# INLINE checked #-} class Property p v where -- | Test if the property holds for the given value. -- The first argument is supposed to be ignored. holds ∷ p → v → Bool -- | Return 'Just' /v/ if /p/ holds and 'Nothing' overwise. maybeHolds ∷ Property p v ⇒ p → v → Maybe v maybeHolds p v | holds p v = Just v | otherwise = Nothing {-# INLINABLE maybeHolds #-} -- | Wrap the value if the property holds. check ∷ ∀ p v . Property p v ⇒ v → Maybe (Checked p v) check v | holds (undefined ∷ p) v = Just (Checked v) | otherwise = Nothing {-# INLINABLE check #-}