summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data-checked.cabal3
-rw-r--r--src/Data/Checked.hs1
-rw-r--r--src/Data/Checked/Strict.hs56
3 files changed, 58 insertions, 2 deletions
diff --git a/data-checked.cabal b/data-checked.cabal
index 9f6f73b..deca5ad 100644
--- a/data-checked.cabal
+++ b/data-checked.cabal
@@ -1,5 +1,5 @@
Name: data-checked
-Version: 0.2
+Version: 0.3
Category: Data
Stability: experimental
Synopsis: Type-indexed runtime-checked properties
@@ -30,4 +30,5 @@ Library
GHC-Options: -Wall
Exposed-Modules:
Data.Checked
+ Data.Checked.Strict
diff --git a/src/Data/Checked.hs b/src/Data/Checked.hs
index bc1e916..a53f63a 100644
--- a/src/Data/Checked.hs
+++ b/src/Data/Checked.hs
@@ -60,4 +60,3 @@ check ∷ ∀ p v . Property p v ⇒ v → Maybe (Checked p v)
check v | holds (undefined ∷ p) v = Just (Checked v)
| otherwise = Nothing
{-# INLINABLE check #-}
-
diff --git a/src/Data/Checked/Strict.hs b/src/Data/Checked/Strict.hs
new file mode 100644
index 0000000..7acd94f
--- /dev/null
+++ b/src/Data/Checked/Strict.hs
@@ -0,0 +1,56 @@
+{-# LANGUAGE UnicodeSyntax #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+-- | A version of 'DC.Checked' that requires client code to provide
+-- a non-bottom value of the property index type to use @trust*@
+-- functions.
+module Data.Checked.Strict
+ ( Checked
+ , trustThat
+ , trustMap
+ , checked
+ , Property(..)
+ , maybeHolds
+ , check
+ , relax
+ ) where
+
+import Data.Typeable (Typeable)
+import Control.DeepSeq (NFData(..))
+import Data.Checked (Property(..), maybeHolds)
+import qualified Data.Checked as DC
+
+-- | Wrapper-evidence for property /p/.
+newtype Checked p v = Checked v deriving Typeable
+
+instance NFData v ⇒ NFData (Checked p v) where
+ rnf (Checked v) = rnf v
+
+-- | Use when the property can be deduced without a runtime check.
+-- Note that /p/ is evaluated to WHNF, so you can't use 'undefined'.
+trustThat ∷ p → v → Checked p v
+trustThat p v = p `seq` Checked v
+{-# INLINE trustThat #-}
+
+-- | Apply a fuction that preserves the property to the checked value.
+-- Note that /p/ is evaluated to WHNF, so you can't use 'undefined'.
+trustMap ∷ p → (v → v) → Checked p v → Checked p v
+trustMap p f (Checked v) = p `seq` Checked (f v)
+{-# INLINE trustMap #-}
+
+-- | Unwrap the checked value.
+checked ∷ Checked p v → v
+checked (Checked v) = v
+{-# INLINE checked #-}
+
+-- | 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 #-}
+
+-- | Rewrap a value into the less strict 'DC.Checked' type.
+relax ∷ Checked p v → DC.Checked p v
+relax (Checked v) = DC.trustMe v
+{-# INLINE relax #-}