data-checked-0.1: src/Data/Checked.hs
{-# 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 #-}