Permalink
Browse files

Made the combinators in Data.Constraints.Unsafe sound less safe.

  • Loading branch information...
1 parent c06e884 commit 740058f756e2d5155b04f3f2a9b55c74bb737f57 @ekmett committed Apr 7, 2012
Showing with 62 additions and 20 deletions.
  1. +14 −0 Data/Constraint.hs
  2. +16 −2 Data/Constraint/Forall.hs
  3. +31 −17 Data/Constraint/Unsafe.hs
  4. +1 −1 constraints.cabal
View
@@ -11,6 +11,18 @@
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE GADTs #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : Data.Constraint
+-- Copyright : (C) 2011-2012 Edward Kmett,
+-- License : BSD-style (see the file LICENSE)
+--
+-- Maintainer : Edward Kmett <ekmett@gmail.com>
+-- Stability : experimental
+-- Portability : non-portable
+--
+----------------------------------------------------------------------------
+
module Data.Constraint
(
@@ -111,10 +123,12 @@ refl = Sub Dict
top :: a :- ()
top = Sub Dict
+-- | Reify the relationship between a class and its superclass constraints as a class
class Class b h | h -> b where
cls :: h :- b
infixr 9 :=>
+-- | Reify the relationship between an instance head and its body as a class
class b :=> h | h -> b where
ins :: b :- h
View
@@ -6,6 +6,17 @@
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE Trustworthy #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : Data.Constraint.Forall
+-- Copyright : (C) 2011-2012 Edward Kmett,
+-- License : BSD-style (see the file LICENSE)
+--
+-- Maintainer : Edward Kmett <ekmett@gmail.com>
+-- Stability : experimental
+-- Portability : non-portable
+--
+----------------------------------------------------------------------------
module Data.Constraint.Forall
( Forall, inst
@@ -18,14 +29,17 @@ import Data.Constraint.Unsafe
-- skolem variables, do not export!
data A
data B
+-- | A quantified constraint
type Forall (p :: * -> Constraint) = (p A, p B)
data F a
data M a
type Forall1 (p :: (* -> *) -> Constraint) = (p F, p M)
+-- | instantiate a quantified constraint on kind @*@
inst :: forall p a. Forall p :- p a
-inst = trans (evil :: p A :- p a) weaken1
+inst = trans (unsafeCoerceConstraint :: p A :- p a) weaken1
+-- | instantiate a quantified constraint on kind @* -> *@
inst1 :: forall (p :: (* -> *) -> Constraint) (f :: * -> *). Forall1 p :- p f
-inst1 = trans (evil :: p F :- p f) weaken1
+inst1 = trans (unsafeCoerceConstraint :: p F :- p f) weaken1
View
@@ -7,14 +7,24 @@
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE GADTs #-}
-
+-----------------------------------------------------------------------------
+-- |
+-- Module : Data.Constraint.Unsafe
+-- Copyright : (C) 2011-2012 Edward Kmett
+-- License : BSD-style (see the file LICENSE)
+--
+-- Maintainer : Edward Kmett <ekmett@gmail.com>
+-- Stability : experimental
+-- Portability : non-portable
+--
+----------------------------------------------------------------------------
module Data.Constraint.Unsafe
- ( evil
- , derive
- , underive
+ ( unsafeCoerceConstraint
+ , unsafeDerive
+ , unsafeUnderive
-- * Sugar
- , applicative
- , alternative
+ , unsafeApplicative
+ , unsafeAlternative
) where
import Control.Applicative
@@ -23,18 +33,22 @@ import Control.Newtype
import Data.Constraint
import Unsafe.Coerce
-evil :: a :- b
-evil = unsafeCoerce refl
-
-derive :: Newtype n o => (o -> n) -> t o :- t n
-derive _ = evil
+-- | Coerce a dictionary unsafely from one type to another
+unsafeCoerceConstraint :: a :- b
+unsafeCoerceConstraint = unsafeCoerce refl
-underive :: Newtype n o => (o -> n) -> t n :- t o
-underive _ = evil
+-- | Coerce a dictionary unsafely from one type to a newtype of that type
+unsafeDerive :: Newtype n o => (o -> n) -> t o :- t n
+unsafeDerive _ = unsafeCoerceConstraint
-applicative :: forall m a. Monad m => (Applicative m => m a) -> m a
-applicative m = m \\ trans (evil :: Applicative (WrappedMonad m) :- Applicative m) ins
+-- | Coerce a dictionary unsafely from a newtype of a type to the base type
+unsafeUnderive :: Newtype n o => (o -> n) -> t n :- t o
+unsafeUnderive _ = unsafeCoerceConstraint
-alternative :: forall m a. MonadPlus m => (Alternative m => m a) -> m a
-alternative m = m \\ trans (evil :: Alternative (WrappedMonad m) :- Alternative m) ins
+-- | Construct an Applicative instance from a Monad
+unsafeApplicative :: forall m a. Monad m => (Applicative m => m a) -> m a
+unsafeApplicative m = m \\ trans (unsafeCoerceConstraint :: Applicative (WrappedMonad m) :- Applicative m) ins
+-- | Construct an Alternative instance from a MonadPlus
+unsafeAlternative :: forall m a. MonadPlus m => (Alternative m => m a) -> m a
+unsafeAlternative m = m \\ trans (unsafeCoerceConstraint :: Alternative (WrappedMonad m) :- Alternative m) ins
View
@@ -1,6 +1,6 @@
name: constraints
category: Constraints
-version: 0.2
+version: 0.3
license: BSD3
cabal-version: >= 1.10
license-file: LICENSE

0 comments on commit 740058f

Please sign in to comment.