flexiwrap 0.0.1 → 0.1.0
raw patch · 27 files changed
+1441/−95 lines, 27 filesdep +QuickCheckdep ~data-type
Dependencies added: QuickCheck
Dependency ranges changed: data-type
Files
- CHANGES +31/−0
- Data/Flex/Applicative.hs +27/−2
- Data/Flex/Arbitrary.hs +16/−0
- Data/Flex/Compose.hs +1/−1
- Data/Flex/FlipT.hs +1/−1
- Data/Flex/Functor.hs +21/−2
- Data/Flex/Monad.hs +30/−2
- Data/Flex/MonadPlus.hs +1/−1
- Data/Flex/MonadState.hs +1/−1
- Data/Flex/MonadTrans.hs +1/−1
- Data/Flex/QuickCheck/Wrap.hs +82/−0
- Data/Flex/SmallCheck/Wrap.hs +0/−51
- Data/Flex/Test/Compose.hs +1/−1
- Data/Flex/Test/Wrap.hs +1/−1
- Data/Flex/Test/WrappedMonad.hs +1/−1
- Data/Flex/Utils.hs +39/−9
- Data/Flex/Wrap.hs +602/−13
- Data/Flex/WrapCTC.hs +1/−1
- Data/Flex/WrapT.hs +1/−1
- Data/Flex/WrappedMonad.hs +1/−1
- LICENSE +1/−1
- README +12/−0
- TODO +14/−0
- doc/intro.txt +155/−0
- flexiwrap.cabal +12/−4
- test/.ghci +3/−0
- test/Data/Flex/SmallCheck/Wrap.hs +385/−0
+ CHANGES view
@@ -0,0 +1,31 @@+== Version 0.1.0 == + +* Added Data/Flex/Arbitrary.hs (utility module for Arbitrary instances) + +* Added instances for Ord, Show, Read, Arbitrary, Monoid to FlexiWrap + (Data/Flex/Wrap.hs) + +* Added Haddock documentation to + Data/Flex/Applicative.hs + Data/Flex/Functor.hs + Data/Flex/Monad.hs + Data/Flex/Utils.hs + Data/Flex/Wrap.hs + +* Added doc/intro.txt + +* Added TODO, README, CHANGES (this file) + +* Added Data/Flex/QuickCheck/Wrap.hs test file + +* Moved Data/Flex/SmallCheck/Wrap.hs to test/Data/Flex/SmallCheck/Wrap.hs, + and added test/.ghci + +* New related package flexiwrap-smallcheck containing Serial instances + (for FlexiWrap at the moment) + +== Version 0.0.1 == + +Initial version + +$Header: c:/Source/Haskell/Wrapper/RCS/CHANGES,v 1.1 2011/09/20 23:52:58 dosuser Exp dosuser $
Data/Flex/Applicative.hs view
@@ -2,19 +2,44 @@ {-# LANGUAGE PolymorphicComponents #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} --- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Applicative.hs,v 1.1 2010/03/10 01:56:44 dosuser Exp dosuser $ -module Data.Flex.Applicative where +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Applicative.hs,v 1.3 2011/09/20 23:35:55 dosuser Exp dosuser $ +module Data.Flex.Applicative ( + -- * Common flexible Applicative instance selection types and classes + -- ** Analysis class for @'Applicative'@ instance selection + FWApplicative, + -- ** Instance selectors + FWDefaultApplicative(..), + -- ** Function identifier types for @'Apply'@ + FWPure(..), + FWCombine(..), + -- ** Polymorphic function wrappers + WrapPure(..), + WrapCombine(..) +) where +-- | Analysis class for @'Applicative'@ instance selection +-- You need a specific instance of this for any instance selectors +-- you may define. class FWApplicative (f :: * -> *) r | f -> r +-- | Instance selector type for the default @'Applicative'@ +-- instances data FWDefaultApplicative = FWDefaultApplicative +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. data FWPure t (f :: * -> *) = FWPure +-- | Polymorphic function wrapper for @'pure'@ newtype WrapPure f = WrapPure {unwrapPure :: forall a. a -> f a} +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. data FWCombine t (f :: * -> *) = FWCombine +-- | Polymorphic function wrapper for @'<*>'@ newtype WrapCombine f = WrapCombine {unwrapCombine :: forall a b. f (a -> b) -> (f a -> f b)}
+ Data/Flex/Arbitrary.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE Rank2Types #-} +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Arbitrary.hs,v 1.1 2011/06/10 00:56:23 dosuser Exp dosuser $ +module Data.Flex.Arbitrary ( + -- * Polymorphic function wrapper + WrapCoarbitrary(..) +) where + +import Test.QuickCheck (Gen) + +-- | Polymorphic function wrapper for @'coarbitrary'@ +newtype WrapCoarbitrary = WrapCoarbitrary { + unwrapCoarbitrary :: forall b. Gen b -> Gen b + } + +-- vim: expandtab:tabstop=4:shiftwidth=4
Data/Flex/Compose.hs view
@@ -4,7 +4,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE Rank2Types #-} {-# LANGUAGE OverlappingInstances #-} --- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Compose.hs,v 1.14 2010/12/04 01:40:54 dosuser Exp dosuser $ +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Compose.hs,v 1.15 2011/03/05 00:55:46 dosuser Exp dosuser $ module Data.Flex.Compose where import Control.Monad (liftM, liftM2, join, MonadPlus(..))
Data/Flex/FlipT.hs view
@@ -4,7 +4,7 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} --- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/FlipT.hs,v 1.8 2010/11/27 00:41:20 dosuser Exp dosuser $ +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/FlipT.hs,v 1.9 2011/03/05 00:57:29 dosuser Exp dosuser $ module Data.Flex.FlipT where import Control.Monad (MonadPlus(..))
Data/Flex/Functor.hs view
@@ -1,14 +1,33 @@ {-# LANGUAGE ScopedTypeVariables, PolymorphicComponents #-} {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} --- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Functor.hs,v 1.2 2010/03/12 23:46:00 dosuser Exp dosuser $ -module Data.Flex.Functor where +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Functor.hs,v 1.4 2011/09/20 23:36:59 dosuser Exp dosuser $ +module Data.Flex.Functor ( + -- * Common flexible Functor instance selection types and classes + -- ** Analysis class for @'Functor'@ instance selection + FWFunctor, + -- ** Instance selector + FWDefaultFunctor(..), + -- ** Function identifier type for @'Apply'@ + FWFmap(..), + -- ** Polymorphic function wrapper + WrapFmap(..) +) where +-- | Analysis class for @'Functor'@ instance selection +-- You need a specific instance of this for any instance selectors +-- you may define. class FWFunctor (f :: * -> *) r | f -> r +-- | Instance selector type for the default @'Functor'@ +-- instances data FWDefaultFunctor = FWDefaultFunctor +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. data FWFmap t (f :: * -> *) = FWFmap +-- | Polymorphic function wrapper for @'fmap'@ newtype WrapFmap f = WrapFmap {unwrapFmap :: forall a b. (a -> b) -> (f a -> f b)}
Data/Flex/Monad.hs view
@@ -1,16 +1,40 @@ {-# LANGUAGE ScopedTypeVariables, Rank2Types #-} {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} --- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Monad.hs,v 1.1 2010/03/10 01:57:35 dosuser Exp dosuser $ -module Data.Flex.Monad where +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Monad.hs,v 1.3 2011/09/20 23:37:34 dosuser Exp dosuser $ +module Data.Flex.Monad ( + -- * Common flexible Monad instance selection types and classes + -- ** Analysis class for @'Monad'@ instance selection + FWMonad, + -- ** Instance selectors + FWDefaultMonad(..), + -- ** Function identifier types for @'Apply'@ + FWReturn(..), + FWBind(..), + -- ** Polymorphic function wrappers + WrapReturn(..), + WrapBind(..), + -- ** Constructor aliases + wrapReturn, + wrapBind +) where -- import Data.Flex.Applicative (WrapPure(..)) +-- | Analysis class for @'Monad'@ instance selection +-- You need a specific instance of this for any instance selectors +-- you may define. class FWMonad (m :: * -> *) r | m -> r +-- | Instance selector type for the default @'Monad'@ +-- instances data FWDefaultMonad = FWDefaultMonad +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. data FWReturn t (m :: * -> *) = FWReturn +-- | Polymorphic function wrapper for @'return'@ newtype WrapReturn m = WrapReturn {unwrapReturn :: forall a. a -> m a} wrapReturn :: (forall a. a -> m a) -> WrapReturn m wrapReturn = WrapReturn @@ -22,8 +46,12 @@ unwrapReturn = unwrapPure -} +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. data FWBind t (m :: * -> *) = FWBind +-- | Polymorphic function wrapper for @'>>='@ newtype WrapBind m = WrapBind {unwrapBind :: forall a b. m a -> (a -> m b) -> m b}
Data/Flex/MonadPlus.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE ScopedTypeVariables, PolymorphicComponents #-} {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} --- .$Header$ +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/MonadPlus.hs,v 1.2 2011/03/05 01:02:51 dosuser Exp dosuser $ module Data.Flex.MonadPlus where class FWMonadPlus (m :: * -> *) r | m -> r
Data/Flex/MonadState.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE ScopedTypeVariables, PolymorphicComponents #-} {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} --- .$Header$ +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/MonadState.hs,v 1.1 2011/03/05 01:03:51 dosuser Exp dosuser $ module Data.Flex.MonadState where class FWMonadState (m :: * -> *) r | m -> r
Data/Flex/MonadTrans.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE ScopedTypeVariables, PolymorphicComponents #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} --- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/MonadTrans.hs,v 1.2 2010/03/12 23:46:34 dosuser Exp dosuser $ +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/MonadTrans.hs,v 1.3 2011/03/05 01:04:22 dosuser Exp dosuser $ module Data.Flex.MonadTrans where class FWMonadTrans (f :: (* -> *) -> (* -> *)) a | f -> a
+ Data/Flex/QuickCheck/Wrap.hs view
@@ -0,0 +1,82 @@+-- $Header: c:/Source/Haskell/Wrapper/Data/Flex/QuickCheck/RCS/Wrap.hs,v 1.1 2011/06/04 00:46:28 dosuser Exp dosuser $ + +-- | QuickCheck tests for Data.Flex.Wrap + +module Data.Flex.QuickCheck.Wrap where + +import Test.QuickCheck + +import Data.Type.TList (TNil(..), (:*:)(..)) + +import Data.Flex.Wrap + +prop_defaultArbitrary_is_transparent i = forAll rand $ \g -> + generate ai g wx == w (generate ai g x) + where + w = flexiWrap TNil + {- N.B. The following circumlocution is necessary because + fmap / liftM in the Gen monad split the PRNG + -} + x = fmap id arbitrary :: Gen Int + wx = arbitrary + ai = abs i + +prop_defaultCoarbitrary_is_transparent i a b = forAll rand $ \g -> + generate ai g wx == generate ai g x + where + ai = abs i + w = flexiWrap TNil + x = coarbitrary a $ return b + wx = coarbitrary (w a) $ return b + types = (a :: Int, b :: Int) + +prop_transparentArbitrary_is_transparent i = forAll rand $ \g -> + generate ai g wx == w (generate ai g x) + where + w = flexiWrap (FWTransparentArbitrary :*: TNil) + {- N.B. The following circumlocution is necessary because + fmap / liftM in the Gen monad split the PRNG + -} + x = fmap id arbitrary :: Gen Int + wx = arbitrary + ai = abs i + +prop_transparentCoarbitrary_is_transparent i a b = forAll rand $ \g -> + generate ai g wx == generate ai g x + where + ai = abs i + w = flexiWrap (FWTransparentArbitrary :*: TNil) + x = coarbitrary a $ return b + wx = coarbitrary (w a) $ return b + types = (a :: Int, b :: Int) + +prop_explicitDefaultArbitrary_is_transparent i = forAll rand $ \g -> + generate ai g wx == w (generate ai g x) + where + w = flexiWrap (FWDefaultArbitrary :*: TNil) + {- N.B. The following circumlocution is necessary because + fmap / liftM in the Gen monad split the PRNG + -} + x = fmap id arbitrary :: Gen Int + wx = arbitrary + ai = abs i + +prop_explicitDefaultCoarbitrary_is_transparent i a b = forAll rand $ \g -> + generate ai g wx == generate ai g x + where + ai = abs i + w = flexiWrap (FWDefaultArbitrary :*: TNil) + x = coarbitrary a $ return b + wx = coarbitrary (w a) $ return b + types = (a :: Int, b :: Int) + +testArbitrary :: IO () +testArbitrary = do + quickCheck prop_defaultArbitrary_is_transparent + quickCheck prop_defaultCoarbitrary_is_transparent + quickCheck prop_transparentArbitrary_is_transparent + quickCheck prop_transparentCoarbitrary_is_transparent + quickCheck prop_explicitDefaultArbitrary_is_transparent + quickCheck prop_explicitDefaultCoarbitrary_is_transparent + +-- vim: expandtab:tabstop=4:shiftwidth=4
− Data/Flex/SmallCheck/Wrap.hs
@@ -1,51 +0,0 @@-{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE TypeSynonymInstances #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE UndecidableInstances #-} --- $Header: c:/Source/Haskell/Wrapper/Data/Flex/SmallCheck/RCS/Wrap.hs,v 1.2 2010/03/13 00:11:09 dosuser Exp dosuser $ -module Data.Flex.SmallCheck.Wrap where - -import Test.SmallCheck - -{- -import Control.Applicative ((<$>)) - -import Data.Wrap (result, argument) --} - -import Data.Type.Apply (Apply(..)) -import Data.Type.Eq (TypeCast) -import Data.Type.TList ((:*:), TNil) - -import Data.Flex.Wrap - -{- -import Data.Flex.SmallCheck.Instances --} - -data X = X - -prop_default_Eq_is_Eq x y = (x == y) == (w x == w y) where - w = fWrap X :: Bool -> FW (X :*: TNil) Bool - types = x :: Bool - -data FWEqFirst = FWEqFirst - -instance TypeCast r FWEqFirst => FWEq (FW (FWEqFirst :*: s) a) r - -instance Eq a => - Apply (FWEquals t (a, b)) FWEqFirst (FW t (a, b) -> FW t (a, b) -> Bool) - where - apply _ _ = (==) `on` fst . unFlexiWrap - -instance Eq a => - Apply (FWNotEquals t (a, b)) FWEqFirst (FW t (a, b) -> FW t (a, b) -> Bool) - where - apply _ _ = (/=) `on` fst `on` unFlexiWrap - -prop_EqFirst_is_Eq_fst x y = (x `eqFst` y) == (w x == w y) where - eqFst = (==) `on` fst - w = FlexiWrap :: (Bool, Bool) -> FW (FWEqFirst :*: TNil) (Bool, Bool) - --- vim: expandtab:tabstop=4:shiftwidth=4
Data/Flex/Test/Compose.hs view
@@ -1,4 +1,4 @@--- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/Test/RCS/Compose.hs,v 1.5 2010/04/24 00:59:15 dosuser Exp dosuser $ +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/Test/RCS/Compose.hs,v 1.6 2011/03/05 01:28:41 dosuser Exp dosuser $ module Data.Flex.Test.Compose where import Control.Monad (MonadPlus(..))
Data/Flex/Test/Wrap.hs view
@@ -1,4 +1,4 @@--- $Header: c:/Source/Haskell/Wrapper/Data/Flex/Test/RCS/Wrap.hs,v 1.4 2010/02/05 00:39:46 dosuser Exp dosuser $ +-- $Header: c:/Source/Haskell/Wrapper/Data/Flex/Test/RCS/Wrap.hs,v 1.5 2011/03/05 01:29:46 dosuser Exp dosuser $ module Data.Flex.Test.Wrap where import Data.Flex.Wrap
Data/Flex/Test/WrappedMonad.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE FlexibleContexts #-} --- .$Header$ +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/Test/RCS/WrappedMonad.hs,v 1.4 2011/03/05 01:30:24 dosuser Exp dosuser $ module Data.Flex.Test.WrappedMonad where import Control.Applicative (Applicative(..))
Data/Flex/Utils.hs view
@@ -1,27 +1,57 @@ {-# LANGUAGE ScopedTypeVariables, Rank2Types #-} --- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Utils.hs,v 1.1 2010/11/26 23:54:58 dosuser Exp dosuser $ -module Data.Flex.Utils (inCompose, inCompose2, bindWrapper) where +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Utils.hs,v 1.5 2011/09/20 23:38:55 dosuser Exp dosuser $ +module Data.Flex.Utils ( + -- * Various utility functions for handling wrappers + -- ** Wrapper/unwrapper composition + inCompose, inCompose2, + -- ** Constructing @'Monad'@ bind (@'>>='@) for wrapped values + bindWrapper, + -- ** Another popular composition combinator + on + -- ** Semantic editor combinators + -- (<http://conal.net/blog/posts/semantic-editor-combinators/>) + , result, argument +) where +-- | Place (by composition) two functions round another function circumpose :: (c -> d) -> (a -> b) -> (b -> c) -> (a -> d) circumpose left right = (left .) . (. right) +-- | Bracket (by composition) a function by two other functions. +-- (\'In' as in infix.) + +-- Sometimes more convenient than @'circumpose'@ inCompose :: (a -> b) -> (c -> d) -> (b -> c) -> (a -> d) inCompose = flip circumpose +-- | A generalisation of @'inCompose'@ to two-argument functions inCompose2 :: (forall a. f a -> a) -> (d -> e) -> (b -> c -> d) -> (f b -> f c -> e) inCompose2 unwrap wrap = inCompose unwrap $ inCompose unwrap wrap +-- | Change the result of a function result :: (b -> c) -> (a -> b) -> (a -> c) result = (.) --- Utility function to construct (>>=) for a target monad <t> from the (>>=) --- for an implementation monad <i> --- Parameters: --- wrap: function from target monad to implementation monad (t a -> i a) --- unwrap: vice versa (i a -> t a) -bindWrapper :: (forall q. f q -> g q) -> (d -> e) -> (g a -> (c -> g b) -> d) -> - f a -> (c -> f b) -> e +-- | Change the argument of a function +argument :: (a -> b) -> (b -> c) -> (a -> c) +argument = flip (.) + +-- | Handy utility function +infixl 8 `on` +on :: (b -> b -> c) -> (a -> b) -> (a -> a -> c) +(op `on` f) x y = f x `op` f y + +-- | Utility function to construct @'>>='@ for a target monad @t@ from +-- the @'>>='@ from an implementation monad @i@ +bindWrapper :: + (forall q. t q -> i q) + -- ^ wrap: function from target monad to implementation monad + -> (d -> e) + -- ^ unwrap: vice versa (@i q -> t q@) + -> (i a -> (c -> i b) -> d) + -- ^ @'>>='@ in the implementation monad + -> t a -> (c -> t b) -> e bindWrapper wrap unwrap = inCompose wrap $ inCompose (result wrap) unwrap -- vim: expandtab:tabstop=4:shiftwidth=4
Data/Flex/Wrap.hs view
@@ -1,42 +1,119 @@ {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE Rank2Types #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverlappingInstances #-} --- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Wrap.hs,v 1.13 2010/04/24 00:47:40 dosuser Exp dosuser $ -module Data.Flex.Wrap where +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/Wrap.hs,v 1.18 2011/09/20 23:46:14 dosuser Exp dosuser $ +-- | The flexible value wrapper @'FlexiWrap'@ and associated types and classes + +module Data.Flex.Wrap ( + -- * @'FlexiWrap'@ + -- | and related instance machinery + + -- ** @'FlexiWrap'@ + -- | with a type synonym and alternative constructors + FlexiWrap(..), + FW, + flexiWrap, + flexiWrapP, + -- ** Instance selectors + FWDefaultEq(..), + FWTransparentEq(..), + FWDefaultOrd(..), + FWTransparentOrd(..), + FWReverseOrd(..), + FWDefaultShowRead(..), + FWLiteralShowRead(..), + FWTransparentShowRead(..), + FWDefaultArbitrary(..), + FWTransparentArbitrary(..), + FWDefaultMonoid(..), + FWTransparentMonoid(..), + FWDualMonoid(..), + FWEndoMonoid(..), + FWAllMonoid(..), + FWAnyMonoid(..), + FWSumMonoid(..), + FWProductMonoid(..), + FWFirstMonoid(..), + FWLastMonoid(..), + -- ** Machinery for @'Eq'@ instances + FWEq, + FWEquals(..), + FWNotEquals(..), + -- ** Machinery for @'Ord'@ instances + FWOrd, + FWCompare(..), + -- ** Machinery for @'Show'@ and @'Read'@ instances + FWShowRead, + FWShow(..), + FWRead(..), + -- ** Machinery for @'Arbitrary'@ instances + FWArbitraryC, + FWArbitrary(..), + FWCoarbitrary(..), + -- ** Machinery for @'Monoid'@ instances + FWMonoid, + FWMempty(..), + FWMappend(..), + -- ** Utility functions + inFlexiWrap, + inFlexiWrap2, + -- * Experimental features + FWNormAppend, + FWrap(..), + FWIsWrapped, + FWAlreadyWrapped(..), + FWNewWrapper(..) +) where + import Control.Applicative (Applicative(..)) -- , (<$>), liftA2, Alternative(..)) import Data.Foldable as F (Foldable(..)) +import Data.Monoid (Monoid(..)) import qualified Data.Traversable as T (Traversable(..)) +import Test.QuickCheck (Arbitrary(..), Gen) + import Data.Type.Apply (Apply(..)) import Data.Type.Eq (TypeCast) +import Data.Type.Proxy (Proxy(..)) import Data.Type.TList ((:*:), TNil) -import Data.Flex.Utils (inCompose, inCompose2) +import Data.Flex.Arbitrary (WrapCoarbitrary(..)) +import Data.Flex.Utils (inCompose, inCompose2, on) -- begin FlexiWrap +-- | The flexible value wrapper newtype FlexiWrap s a = FlexiWrap {unFlexiWrap :: a} +-- | A handy abbreviated type synonym type FW = FlexiWrap +-- | An alternative constructor flexiWrap :: s -> a -> FW s a flexiWrap _ = FlexiWrap +-- | An alternative constructor using a proxy +flexiWrapP :: Proxy s -> a -> FW s a +flexiWrapP _ = FlexiWrap + +-- | The implementation of fmap for @'Functor' ('FW' s)@ inFlexiWrap :: (a -> b) -> (FW s a -> FW s b) inFlexiWrap = inCompose unFlexiWrap FlexiWrap +-- | An extension of fmap to two-argument functions inFlexiWrap2 :: (a -> b -> c) -> (FW s a -> FW s b -> FW s c) -- inFlexiWrap2 = inCompose unFlexiWrap $ inCompose unFlexiWrap FlexiWrap inFlexiWrap2 = inCompose2 unFlexiWrap FlexiWrap --- TODO: Use flexible instance machinery +-- TODO: Use flexible instance machinery? instance Functor (FW t) where fmap = inFlexiWrap @@ -56,8 +133,10 @@ return = FlexiWrap (>>=) = flip (. unFlexiWrap) --- append <s> and <t> to produce <u> --- <s> may or may not be terminated by TNil +-- | Utility class to append two type-level lists +-- +-- append \<s> and \<t> to produce \<u>. +-- \<s> may or may not be terminated by @'TNil'@; -- if so, it does not appear in the result class FWNormAppend s t u | s t -> u @@ -67,30 +146,43 @@ instance TypeCast u (x :*: t) => FWNormAppend x t u +-- | Utility class to create or tag-extend a wrapper + -- class FWrap w a b where class FWrap w a b | w a -> b where fWrap :: w -> a -> b +-- | Analysis class to determine whether an argument is already wrapped, +-- used for @'FWrap'@ class FWIsWrapped a r | a -> r +-- | Result type for @'FWIsWrapped'@ data FWAlreadyWrapped = FWAlreadyWrapped +-- | Result type for @'FWIsWrapped'@ data FWNewWrapper = FWNewWrapper +-- | Function identifier type for @'Apply'@ data FWFWrap s a = FWFWrap instance FWIsWrapped (FW s a) FWAlreadyWrapped instance TypeCast r FWNewWrapper => FWIsWrapped a r +-- | * Implementation instance for @'FWrap'@ instance Apply (FWFWrap u a) FWNewWrapper (a -> FW u a) where apply _ _ = FlexiWrap +-- | * Implementation instance for @'FWrap'@ instance Apply (FWFWrap u (FW s a)) FWAlreadyWrapped (FW s a -> FW u a) where apply _ _ = FlexiWrap . unFlexiWrap +-- | Function identifier type for @'Apply'@ data FWTag +-- | * Analysis instance for @'FWTag'@ instance Apply FWTag (FW t a) t +-- | * Analysis instance for @'FWTag'@ instance TypeCast r TNil => Apply FWTag a r +-- | * Coordinating instance definition for @'FWrap'@ instance forall a b s t u w. ( Apply FWTag a t, FWNormAppend s t u, @@ -140,31 +232,58 @@ fWrap _ = FlexiWrap -} -infixl 8 `on` -on :: (b -> b -> c) -> (a -> b) -> (a -> a -> c) -(op `on` f) x y = f x `op` f y +-- TODO: FWDefaultAll (except Num) selector +-- Eq + +-- | Analysis class for @'Eq'@ instance selection. +-- You need a specific instance of this for any instance selectors +-- you may define. class FWEq a r | a -> r +-- | Instance selector type for the default +-- (transparent) implementation of @'Eq'@ data FWDefaultEq = FWDefaultEq +-- | Instance selector type for the (default) +-- transparent implementation of @'Eq'@ +data FWTransparentEq = FWTransparentEq + +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. data FWEquals t a = FWEquals +-- | Function identifier type for @'Apply'@ +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. data FWNotEquals t a = FWNotEquals --- default instance -instance TypeCast r FWDefaultEq => FWEq (FW t a) r +-- | * Default instance +instance TypeCast r FWTransparentEq => FWEq (FW t a) r +-- | * Propagated instance instance FWEq (FW s a) r => FWEq (FW (x :*: s) a) r -instance Eq a => Apply (FWEquals t a) FWDefaultEq (FW t a -> FW t a -> Bool) +-- | * Specific @'FWDefaultEq'@ instance +instance FWShowRead (FW (FWDefaultEq :*: s) a) FWTransparentEq + +-- | * Specific @'FWTransparentEq'@ instance +instance FWShowRead (FW (FWTransparentEq :*: s) a) FWTransparentEq + +-- | * Implementation instance for @'Eq'@ instance selection +instance Eq a => Apply (FWEquals t a) FWTransparentEq + (FW t a -> FW t a -> Bool) where apply _ _ = (==) `on` unFlexiWrap -instance Eq a => Apply (FWNotEquals t a) FWDefaultEq (FW t a -> FW t a -> Bool) +-- | * Implementation instance for @'Eq'@ instance selection +instance Eq a => Apply (FWNotEquals t a) FWTransparentEq + (FW t a -> FW t a -> Bool) where apply _ _ = (/=) `on` unFlexiWrap +-- | * Coordinating instance for @'Eq'@ instance forall t a r. (Apply (FWEquals t a) r (FW t a -> FW t a -> Bool), Apply (FWNotEquals t a) r (FW t a -> FW t a -> Bool), FWEq (FW t a) r @@ -172,6 +291,476 @@ Eq (FW t a) where (==) = apply (undefined :: FWEquals t a) (undefined :: r) (/=) = apply (undefined :: FWNotEquals t a) (undefined :: r) + +-- Ord + +-- | Analysis class for @'Ord'@ instance selection +-- You need a specific instance of this for any instance selectors +-- you may define. +class FWOrd a r | a -> r + +-- | Instance selector type for the default (transparent) @'Ord'@ instance +data FWDefaultOrd = FWDefaultOrd +-- | Instance selector type for the (default) transparent @'Ord'@ instance +data FWTransparentOrd = FWTransparentOrd +-- | Instance selector type for a reversed @'Ord'@ instance +data FWReverseOrd = FWReverseOrd + +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. +data FWCompare t a = FWCompare + +-- | * Default instance +instance TypeCast r FWTransparentOrd => FWOrd (FW t a) r + +-- | * Propagated instance +instance FWOrd (FW s a) r => FWOrd (FW (x :*: s) a) r + +-- | * Specific @'FWDefaultOrd'@ instance +instance FWOrd (FW (FWDefaultOrd :*: s) a) FWTransparentOrd + +-- | * Specific @'FWTransparentOrd'@ instance +instance FWOrd (FW (FWTransparentOrd :*: s) a) FWTransparentOrd + +-- | * Specific @'FWReverseOrd'@ instance +instance FWOrd (FW (FWReverseOrd :*: s) a) FWReverseOrd + +-- | ** Implementation instance for @'Ord'@ instance selection +instance Ord a => Apply (Proxy (FWCompare t a)) (Proxy FWTransparentOrd) + (FW t a -> FW t a -> Ordering) + where + apply _ _ = compare `on` unFlexiWrap + +-- | ** Implementation instance for @'Ord'@ instance selection +instance Ord a => Apply (Proxy (FWCompare t a)) (Proxy FWReverseOrd) + (FW t a -> FW t a -> Ordering) + where + apply _ _ = flip compare `on` unFlexiWrap + +-- | * Coordinating instance of @'Ord'@ +instance forall t a r. ( + Apply (Proxy (FWCompare t a)) (Proxy r) + (FW t a -> FW t a -> Ordering), + FWOrd (FW t a) r, + Eq (FW t a) + ) => + Ord (FW t a) where + compare = apply (Proxy :: Proxy (FWCompare t a)) (Proxy :: Proxy r) + +-- Show/Read + +app_prec :: Int +app_prec = 10 + +-- | Analysis class for @'Show/Read'@ instance selection +-- You need a specific instance of this for any instance selectors +-- you may define. +class FWShowRead a r | a -> r + +-- | Instance selector type for the default (literal) @'Show'/'Read'@ +-- instances +data FWDefaultShowRead = FWDefaultShowRead deriving (Show, Read) + +-- | Instance selector type for the (default) literal @'Show'/'Read'@ +-- instances +data FWLiteralShowRead = FWLiteralShowRead deriving (Show, Read) + +-- | Instance selector type for transparent @'Show'/'Read'@ instances +data FWTransparentShowRead = FWTransparentShowRead deriving (Show, Read) + +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. +data FWShow t a = FWShow + +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. +data FWRead t a = FWRead + +-- | * Default instance +instance TypeCast r FWLiteralShowRead => FWShowRead (FW t a) r + +-- | * Propagated instance +instance FWShowRead (FW s a) r => FWShowRead (FW (x :*: s) a) r + +-- | * Specific @'FWDefaultShowRead'@ instance +instance FWShowRead (FW (FWDefaultShowRead :*: s) a) FWLiteralShowRead + +-- | * Specific @'FWLiteralShowRead'@ instance +instance FWShowRead (FW (FWLiteralShowRead :*: s) a) FWLiteralShowRead + +-- | * Specific @'FWTransparentShowRead'@ instance +instance FWShowRead (FW (FWTransparentShowRead :*: s) a) FWTransparentShowRead + +-- | ** Implementation instance for @'Show'@ instance selection +instance Show a => + Apply (Proxy (FWShow t a)) (Proxy FWLiteralShowRead) + (Int -> FW t a -> ShowS) + where + apply _ _ d (FlexiWrap w) = showParen (d > app_prec) $ + showString "FlexiWrap " . showsPrec (app_prec+1) w + +-- | ** Implementation instance for @'Read'@ instance selection +instance Read a => + Apply (Proxy (FWRead t a)) (Proxy FWLiteralShowRead) + (Int -> ReadS (FW t a)) + where + apply _ _ d r = readParen + (d > app_prec) + (\v -> [(FlexiWrap m, t) | + ("FlexiWrap", s) <- lex v, + (m, t) <- readsPrec (app_prec+1) s + ]) + r + +-- | ** Implementation instance for @'Show'@ instance selection +instance Show a => + Apply (Proxy (FWShow t a)) (Proxy FWTransparentShowRead) + (Int -> FW t a -> ShowS) + where + apply _ _ d (FlexiWrap w) = showParen (d > app_prec) $ + showsPrec (app_prec+1) w + +-- | ** Implementation instance for @'Read'@ instance selection +instance Read a => + Apply (Proxy (FWRead t a)) (Proxy FWTransparentShowRead) + (Int -> ReadS (FW t a)) + where + apply _ _ d r = readParen + (d > app_prec) + (\s -> [(FlexiWrap m, t) | + (m, t) <- readsPrec (app_prec+1) s + ]) + r + +-- | * Coordinating instance of @'Show'@ +instance forall t a r. ( + Apply (Proxy (FWShow t a)) (Proxy r) + (Int -> FW t a -> ShowS), + FWShowRead (FW t a) r + ) => + Show (FW t a) where + showsPrec = apply (Proxy :: Proxy (FWShow t a)) (Proxy :: Proxy r) + +-- | * Coordinating instance of @'Read'@ +instance forall t a r. ( + Apply (Proxy (FWRead t a)) (Proxy r) + (Int -> ReadS (FW t a)), + FWShowRead (FW t a) r + ) => + Read (FW t a) where + readsPrec = apply (Proxy :: Proxy (FWRead t a)) (Proxy :: Proxy r) + +-- Arbitrary + +-- | Analysis class for @'Arbitrary'@ instance selection +-- You need a specific instance of this for any instance selectors +-- you may define. +class FWArbitraryC a r | a -> r + +-- | Instance selector type for the default (transparent) @'Arbitrary'@ +-- instances +data FWDefaultArbitrary = FWDefaultArbitrary deriving (Show, Read) + +-- | Instance selector type for transparent @'Arbitrary'@ instances +data FWTransparentArbitrary = FWTransparentArbitrary deriving (Show, Read) + +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. +data FWArbitrary t a = FWArbitrary + +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. +data FWCoarbitrary t a = FWCoarbitrary + +-- | * Default instance +instance TypeCast r FWTransparentArbitrary => FWArbitraryC (FW t a) r + +-- | * Propagated instance +instance FWArbitraryC (FW s a) r => FWArbitraryC (FW (x :*: s) a) r + +-- | * Specific @'FWDefaultArbitrary'@ instance +instance FWArbitraryC (FW (FWDefaultArbitrary :*: s) a) FWTransparentArbitrary + +-- | * Specific @'FWTransparentArbitrary'@ instance +instance FWArbitraryC (FW (FWTransparentArbitrary :*: s) a) + FWTransparentArbitrary + +-- | ** Implementation instance for @'Arbitrary'@ instance selection +instance Arbitrary a => + Apply (Proxy (FWArbitrary t a)) (Proxy FWTransparentArbitrary) + (Gen (FW t a)) + where + apply _ _ = fmap FlexiWrap arbitrary + +-- | ** Implementation instance for @'Arbitrary'@ instance selection +instance Arbitrary a => + Apply (Proxy (FWCoarbitrary t a)) (Proxy FWTransparentArbitrary) + (FW t a -> WrapCoarbitrary) + where + apply _ _ x = WrapCoarbitrary (coarbitrary $ unFlexiWrap x) + +-- | * Coordinating instance of @'Arbitrary'@ +instance forall t a r. ( + Apply (Proxy (FWArbitrary t a)) (Proxy r) (Gen (FW t a)), + Apply (Proxy (FWCoarbitrary t a)) (Proxy r) + (FW t a -> WrapCoarbitrary), + FWArbitraryC (FW t a) r + ) => + Arbitrary (FW t a) where + arbitrary = apply (Proxy :: Proxy (FWArbitrary t a)) (Proxy :: Proxy r) + coarbitrary = unwrapCoarbitrary . + apply (Proxy :: Proxy (FWCoarbitrary t a)) (Proxy :: Proxy r) + +-- Monoid + +-- | Analysis class for @'Monoid'@ instance selection +-- You need a specific instance of this for any instance selectors +-- you may define. +class FWMonoid a r | a -> r + +-- | Instance selector type for the default (transparent) @'Monoid'@ +-- instances +data FWDefaultMonoid = FWDefaultMonoid deriving (Show, Read) + +-- | Instance selector type for transparent @'Monoid'@ instances +data FWTransparentMonoid = FWTransparentMonoid deriving (Show, Read) + +-- | Instance selector type for dual @'Monoid'@ instances, +-- obtained by swapping the arguments of 'mappend'. +data FWDualMonoid = FWDualMonoid deriving (Show, Read) + +-- Internal version of FWDualMonoid, capturing the subsequent +-- instance selectors +data FWDualMonoidI s = FWDualMonoidI deriving (Show, Read) + +-- | Instance selector type for instances of the @'Monoid'@ of +-- endomorphisms under composition. +data FWEndoMonoid = FWEndoMonoid deriving (Show, Read) + +-- | Instance selector type for instances of the Boolean +-- @'Monoid'@ under conjunction. +data FWAllMonoid = FWAllMonoid deriving (Show, Read) + +-- | Instance selector type for instances of the Boolean +-- @'Monoid'@ under disjunction. +data FWAnyMonoid = FWAnyMonoid deriving (Show, Read) + +-- | Instance selector type for instances of a numeric +-- @'Monoid'@ under addition. +data FWSumMonoid = FWSumMonoid deriving (Show, Read) + +-- | Instance selector type for instances of a numeric +-- @'Monoid'@ under multiplication. +data FWProductMonoid = FWProductMonoid deriving (Show, Read) + +-- | Instance selector type for instances of a +-- Maybe @'Monoid'@ returning the leftmost non-Nothing value. +data FWFirstMonoid = FWFirstMonoid deriving (Show, Read) + +-- | Instance selector type for instances of a +-- Maybe @'Monoid'@ returning the rightmost non-Nothing value. +data FWLastMonoid = FWLastMonoid deriving (Show, Read) + +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. +data FWMempty t a = FWMempty + +-- | Function identifier type for @'Apply'@. +-- You need a corresponding instance of @'Apply'@ for any +-- instance selectors you may define. +data FWMappend t a = FWMappend + +-- | * Default instance +instance TypeCast r FWTransparentMonoid => FWMonoid (FW t a) r + +-- | * Propagated instance +instance FWMonoid (FW s a) r => FWMonoid (FW (x :*: s) a) r + +-- | * Specific @'FWDefaultMonoid'@ instance +instance FWMonoid (FW (FWDefaultMonoid :*: s) a) FWTransparentMonoid + +-- | * Specific @'FWTransparentMonoid'@ instance +instance FWMonoid (FW (FWTransparentMonoid :*: s) a) FWTransparentMonoid + +-- | * Specific @'FWDualMonoid'@ instance +instance FWMonoid (FW (FWDualMonoid :*: s) a) (FWDualMonoidI s) + +-- | * Specific @'FWEndoMonoid'@ instance +instance FWMonoid (FW (FWEndoMonoid :*: s) a) FWEndoMonoid + +-- | * Specific @'FWAllMonoid'@ instance +instance FWMonoid (FW (FWAllMonoid :*: s) a) FWAllMonoid + +-- | * Specific @'FWAnyMonoid'@ instance +instance FWMonoid (FW (FWAnyMonoid :*: s) a) FWAnyMonoid + +-- | * Specific @'FWSumMonoid'@ instance +instance FWMonoid (FW (FWSumMonoid :*: s) a) FWSumMonoid + +-- | * Specific @'FWProductMonoid'@ instance +instance FWMonoid (FW (FWProductMonoid :*: s) a) FWProductMonoid + +-- | * Specific @'FWFirstMonoid'@ instance +instance FWMonoid (FW (FWFirstMonoid :*: s) a) FWFirstMonoid + +-- | * Specific @'FWLastMonoid'@ instance +instance FWMonoid (FW (FWLastMonoid :*: s) a) FWLastMonoid + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Monoid a => + Apply (Proxy (FWMempty t a)) (Proxy FWTransparentMonoid) (FW t a) + where + apply _ _ = FlexiWrap mempty + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Monoid a => + Apply (Proxy (FWMappend t a)) (Proxy FWTransparentMonoid) + (FW t a -> FW t a -> FW t a) + where + apply _ _ = inFlexiWrap2 mappend + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance forall a t s. Monoid (FW s a) => + Apply (Proxy (FWMempty t a)) (Proxy (FWDualMonoidI s)) (FW t a) + where + apply _ _ = FlexiWrap $ unFlexiWrap me + where + me = mempty :: FW s a + +-- TODO: Move inCompose2R to Data.Flex.Utils + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance forall a t s. Monoid (FW s a) => + Apply (Proxy (FWMappend t a)) (Proxy (FWDualMonoidI s)) + (FW t a -> FW t a -> FW t a) + where + apply _ _ = inCompose2R unwrap wrap $ flip mappend + where + inCompose2R :: (forall v. p v -> q v) -> (q d -> e) -> + (q b -> q c -> q d) -> + (p b -> p c -> e) + inCompose2R down up = inCompose down $ inCompose down up + unwrap :: FW t b -> FW s b + unwrap = FlexiWrap . unFlexiWrap + wrap :: FW s a -> FW t a + wrap = FlexiWrap . unFlexiWrap + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Apply (Proxy (FWMempty t (a -> a))) (Proxy FWEndoMonoid) + (FW t (a -> a)) + where + apply _ _ = FlexiWrap id + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Apply (Proxy (FWMappend t (a -> a))) (Proxy FWEndoMonoid) + (FW t (a -> a) -> FW t (a -> a) -> FW t (a -> a)) + where + apply _ _ = inFlexiWrap2 (.) + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Apply (Proxy (FWMempty t Bool)) (Proxy FWAllMonoid) (FW t Bool) + where + apply _ _ = FlexiWrap True + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Apply (Proxy (FWMappend t Bool)) (Proxy FWAllMonoid) + (FW t Bool -> FW t Bool -> FW t Bool) + where + apply _ _ = inFlexiWrap2 (&&) + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Apply (Proxy (FWMempty t Bool)) (Proxy FWAnyMonoid) (FW t Bool) + where + apply _ _ = FlexiWrap False + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Apply (Proxy (FWMappend t Bool)) (Proxy FWAnyMonoid) + (FW t Bool -> FW t Bool -> FW t Bool) + where + apply _ _ = inFlexiWrap2 (||) + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Num a => + Apply (Proxy (FWMempty t a)) (Proxy FWSumMonoid) (FW t a) + where + apply _ _ = FlexiWrap 0 + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Num a => + Apply (Proxy (FWMappend t a)) (Proxy FWSumMonoid) + (FW t a -> FW t a -> FW t a) + where + apply _ _ = inFlexiWrap2 (+) + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Num a => + Apply (Proxy (FWMempty t a)) (Proxy FWProductMonoid) (FW t a) + where + apply _ _ = FlexiWrap 1 + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Num a => + Apply (Proxy (FWMappend t a)) (Proxy FWProductMonoid) + (FW t a -> FW t a -> FW t a) + where + apply _ _ = inFlexiWrap2 (*) + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Apply (Proxy (FWMempty t (Maybe a))) (Proxy FWFirstMonoid) + (FW t (Maybe a)) + where + apply _ _ = FlexiWrap Nothing + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Apply (Proxy (FWMappend t (Maybe a))) (Proxy FWFirstMonoid) + (FW t (Maybe a) -> FW t (Maybe a) -> FW t (Maybe a)) + where + apply _ _ = inFlexiWrap2 f + where + r@(Just _) `f` _ = r + Nothing `f` r = r + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Apply (Proxy (FWMempty t (Maybe a))) (Proxy FWLastMonoid) + (FW t (Maybe a)) + where + apply _ _ = FlexiWrap Nothing + +-- | ** Implementation instance for @'Monoid'@ instance selection +instance Apply (Proxy (FWMappend t (Maybe a))) (Proxy FWLastMonoid) + (FW t (Maybe a) -> FW t (Maybe a) -> FW t (Maybe a)) + where + apply _ _ = inFlexiWrap2 f + where + _ `f` r@(Just _) = r + r `f` Nothing = r + +-- TODO: Min, Max monoids + +-- | * Coordinating instance of @'Monoid'@ +instance forall t a r. ( + Apply (Proxy (FWMempty t a)) (Proxy r) (FW t a), + Apply (Proxy (FWMappend t a)) (Proxy r) + (FW t a -> FW t a -> FW t a), + FWMonoid (FW t a) r + ) => + Monoid (FW t a) where + mempty = apply (Proxy :: Proxy (FWMempty t a)) (Proxy :: Proxy r) + mappend = apply (Proxy :: Proxy (FWMappend t a)) (Proxy :: Proxy r) + +{- TODO: + Num and it's subclasses + Bounded, Enum, Ix + Data, Typeable + Binary + NFData +-} -- end FlexiWrap
Data/Flex/WrapCTC.hs view
@@ -4,7 +4,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE OverlappingInstances #-} --- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/WrapCTC.hs,v 1.4 2010/12/01 00:24:20 dosuser Exp dosuser $ +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/WrapCTC.hs,v 1.5 2011/03/05 01:10:38 dosuser Exp dosuser $ module Data.Flex.WrapCTC where import Control.Monad (MonadPlus(..))
Data/Flex/WrapT.hs view
@@ -5,7 +5,7 @@ {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE OverlappingInstances #-} --- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/WrapT.hs,v 1.9 2010/12/01 00:37:45 dosuser Exp dosuser $ +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/WrapT.hs,v 1.10 2011/03/05 01:15:44 dosuser Exp dosuser $ module Data.Flex.WrapT where import Control.Applicative (Applicative(..))
Data/Flex/WrappedMonad.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} --- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/WrappedMonad.hs,v 1.2 2010/02/10 00:26:03 dosuser Exp dosuser $ +-- .$Header: c:/Source/Haskell/Wrapper/Data/Flex/RCS/WrappedMonad.hs,v 1.3 2011/03/05 01:12:40 dosuser Exp dosuser $ module Data.Flex.WrappedMonad where import Control.Monad (liftM, ap)
LICENSE view
@@ -1,4 +1,4 @@-Copyright Iain Alexander 2010. +Copyright Iain Alexander 2011. All rights reserved. Redistribution and use in source and binary forms, with or without
+ README view
@@ -0,0 +1,12 @@+README for flexiwrap version 0.1.0 + +Use Cabal (http://www.haskell.org/cabal/) to install. + +See doc/intro.txt for an introduction to the concepts. + +Tests are currently in local subdirectories {QuickCheck, SmallCheck, Test} +as appropriate, apart from one in the <test> directory. +The ones in the Test subdirectory are compile-time only tests - +just load them in ghci. + +$Header: c:/Source/Haskell/Wrapper/RCS/README,v 1.1 2011/09/20 23:54:23 dosuser Exp dosuser $
+ TODO view
@@ -0,0 +1,14 @@+Known work outstanding for flexiwrap-0.1.0: + +More typeclasses still needed for FlexiWrap +(see TODO comments in Data/Flex/Wrap.hs) +N.B. some of these may go in separate modules. + +More typeclasses for FlexiWrapT (Data/Flex/WrapT.hs) +and FlexiWrapCTC (Data/Flex/WrapCTC.hs), not commented + +More Haddock (and other) documentation + +Move the rest of the tests into the <test> subdirectory + +$Header: c:/Source/Haskell/Wrapper/RCS/TODO,v 1.1 2011/09/20 23:57:38 dosuser Exp dosuser $
+ doc/intro.txt view
@@ -0,0 +1,155 @@+Subject: Flexible Wrappers - an Introduction + +There are three flexible wrappers provided in the current flexiwrap +package [1]. (More may be required in the future.) + + short long wraps + FW FlexiWrap values + FWT FlexiWrapT unary type constructors + FWCTC FlexiWrapCTC binary operators which combine two + unary type constructors + +The short names are frequently convenient since type signatures can +get quite long. The suffixes are a simple encoding of the kind +of the wrapped quantity, description of which I defer till later. + +The first parameter to each of these is a phantom - it plays no part +in the implementation type, but serves as an index to generate multiple +distinct types from each wrapper. +In addition, by using a type-level list here, we can use it to specify +any number of instance implementations. + +By way of a rather simple example, the module Data.Flex.SmallCheck.Wrap +in the test subdirectory +uses an instance selector called FWReverseOrd to request an +Ord instance which compares values in reverse order, +which you might compare to the Down newtype. It is used there by +using the phantom parameter (FWReverseOrd :*: TNil) resulting in the +(implied) type + + FW (FWReverseOrd :*: TNil) Bool + +which has the requisite properties. + +The current version of the package provides +only a limited number of instance selectors (with the associated +machinery) for each wrapper. +Many of the supplied instances simply delegate to the underlying wrapped type. + +FW (in Data.Flex.Wrap) + +FWTransparentEq (delegates Eq) +FWDefaultEq (alias for FWTransparentEq) +FWTransparentOrd (delegates Ord) +FWDefaultOrd (alias for FWTransparentOrd) +FWReverseOrd (reverses the arguments for Ord) +FWTransparentShowRead (delegates Show and Read) +FWLiteralShowRead (prefixes "FlexiWrap " to the value from the delegated + Show instance, and correspondingly for Read) +FWDefaultShowRead (alias for FWLiteralShowRead) +FWTransparentArbitrary (delegates Arbitrary) +FWDefaultArbitrary (alias for FWTransparentArbitrary) +FWTransparentMonoid (delegates Monoid) +FWDefaultMonoid (alias for FWTransparentMonoid) +FWEndoMonoid (cf. newtype Endo) +FWAllMonoid (cf. newtype All) +FWAnyMonoid (cf. newtype Any) +FWSumMonoid (cf. newtype Sum) +FWProductMonoid (cf. newtype Product) +FWFirstMonoid (cf. newtype First) +FWLastMonoid (cf. newtype Last) +FWDualMonoid (reverses the arguments for the Monoid instance, + such that e.g. (FWDualMonoid :*: FWFirstMonoid :*: TNil) + is equivalent to (FWLastMonoid :*: TNil) + +There is a separate package flexiwrap-smallcheck which supplies instances +of Serial, currently only for FW. + +FWT (Data.Flex.WrapT) has + +FWTDefaultFunctor (Functor) +FWTDefaultApplicative (Applicative) +FWTDefaultMonadAll (the combination of FWTDefaultMonad and + FWTDefaultMonadState) +FWTDefaultMonad (Monad) +FWTDefaultMonadState (MonadState) + +which all again delegate to the underlying type. + +There is also a separate module Data.Flex.WrappedMonad which +provides selectors to implement Functor and Applicative instances +for a Monad which lacks them. + +FWWrapMonad (the combination of FWMonadFunctor and FWMonadApplicative) +FWMonadFunctor (Monad => Functor) +FWMonadApplicative (Monad => Applicative) + +FWCTC (Data.Flex.WrapCTC) has + +FWCTCDefaultFunctor (Functor) +FWCTCDefaultMonad (Monad) + +which simply delegate to the application of the wrapped binary operator +to two constructor arguments, but provides underlying machinery for +these together with MonadPlus and MonadTrans. + +Data.Flex.Compose contains the (:.) (alias O) type composition operator +as found in e.g. the TypeCompose package [2]. It contains a fairly +literal translation of Mark Jones and Luc Duponcheel's scheme for +monad composition [3], + +FWCompP - use the "prod" construction +FWCompD - use the "dorp" construction +FWCompS - use the "swap" construction + +and selectors for MonadTrans and MonadPlus + +FWCompDefaults (the combination of FWCompTrans and FWCompMonadPlus) +FWCompTrans (MonadTrans) +FWCompMonadPlus (a synonym for FWCompMonadPlusR) +FWCompMonadPlusR (using the MonadPlus instance of the right-hand + argument of the composition) +FWCompMonadPlusL (using the MonadPlus instance of the left-hand + argument of the composition) + +Data.Flex.FlipT contains the operator FlipT which flips the +arguments of an operator such as (:.). + +FWFlipDefaults (the combination of FWFlipMonad and FWFlipMonadPlus) +FWFlipMonad (Monad) +FWFlipMonadPlus (MonadPlus) + +These delegate the implementation to the underlying binary operator, +which it wraps with FWCTC, passing the phantom selector list along. + +So, to recap the example given in the initial package release announcement: + +data FWStrict = FWStrict + +type Strict = FW (FWStrict :*: TNil) + +type StrictT = FWCTC + (FWFlipDefaults :*: + FWCompMonadPlusL :*: FWCompDefaults :*: FWCompS :*: TNil + ) + (FlipT O) Strict + +defines a (e.g. monad, but in general constructor) transformer StrictT. +FWCTC is a flexible wrapper. Its first parameter is an HList-like type-level +list of instance specifications. O is the type composition operator, +and FlipT flips its arguments. Strict is a user-defined wrapper type. +(This is strict vs. loose, not strict vs. lazy. It is intended to be +used to wrap values of a data structure which satisfy certain criteria.) +FWCompMonadPlusL specifies a particular MonadPlus instance (which +delegates to the left operand of the composition, which is the right +operand of the flipped composition, i.e. whatever argument you pass +to StrictT), and FWCompS specifies the Jones/Duponcheel SComp +construction [3]. The other two items in the list (apart from the +TNil terminator) specify default implementations of other instances. + +[1] http://hackage.haskell.org/package/flexiwrap-0.1.0 +[2] http://hackage.haskell.org/package/TypeCompose +[3] http://web.cecs.pdx.edu/~mpj/pubs/RR-1004.pdf + +$Header: c:/Source/Haskell/Wrapper/doc/RCS/intro.txt,v 1.3 2011/09/14 01:22:32 dosuser Exp dosuser $ +-- vim: expandtab:tabstop=4:shiftwidth=4
flexiwrap.cabal view
@@ -1,5 +1,5 @@ Name: flexiwrap -Version: 0.0.1 +Version: 0.1.0 Cabal-version: >= 1.2.3 Build-Type: Simple Synopsis: Flexible wrappers @@ -11,7 +11,8 @@ Author: Iain Alexander <ia@stryx.demon.co.uk> Maintainer: Iain Alexander <ia@stryx.demon.co.uk> Build-Type: Simple -Extra-source-files: Data/Flex/SmallCheck/Wrap.hs +Extra-source-files: Data/Flex/QuickCheck/Wrap.hs + , test/Data/Flex/SmallCheck/Wrap.hs , Data/Flex/Test/Compose.hs , Data/Flex/Test/Wrap.hs , Data/Flex/Test/WrappedMonad.hs @@ -19,10 +20,16 @@ , Data/Flex/Examples/Lex/Strict.hs , Data/Wrap.hs , .ghci + , test/.ghci + , README + , CHANGES + , TODO + , doc/intro.txt Tested-with: GHC==6.4.1, GHC==6.6.1, GHC==6.8.3, GHC==6.10.4, GHC==6.12.3 - , GHC==7.0.1 + , GHC==7.0.1, GHC==7.0.4 Library Exposed-Modules: Data.Flex.Applicative + , Data.Flex.Arbitrary , Data.Flex.Compose , Data.Flex.FlipT , Data.Flex.Functor @@ -42,5 +49,6 @@ Ghc-options: -fglasgow-exts if impl(ghc >= 6.8.1) Extensions: TypeOperators, KindSignatures - Build-Depends: base < 5, data-type < 0.1, mtl < 2.1 + Build-Depends: base < 5, data-type >= 0.1 && < 0.2, mtl < 2.1 + , QuickCheck -- vim: expandtab:tabstop=4:shiftwidth=4
+ test/.ghci view
@@ -0,0 +1,3 @@+let extensions= (const . return $ let version = Data.Version.versionBranch System.Info.compilerVersion in if version < [6, 6] then ":set -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances" else if version >= [6, 8] then ":set -XTypeOperators -XKindSignatures" else "") :: String -> IO String +:def extensions extensions +:extensions
+ test/Data/Flex/SmallCheck/Wrap.hs view
@@ -0,0 +1,385 @@+{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TypeSynonymInstances #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE UndecidableInstances #-} +-- $Header: c:/Source/Haskell/Wrapper/test/Data/Flex/SmallCheck/RCS/Wrap.hs,v 1.9 2011/09/20 23:50:10 dosuser Exp dosuser $ + +-- | SmallCheck tests for Data.Flex.Wrap + +module Data.Flex.SmallCheck.Wrap where + +import Test.SmallCheck + +{- +import Control.Applicative ((<$>)) + +import Data.Wrap (result, argument) +-} + +import Data.Monoid (Monoid(..)) + +import Data.Type.Apply (Apply(..)) +import Data.Type.Eq (TypeCast) +import Data.Type.TList ((:*:)(..), TNil(..)) + +import Data.Flex.Wrap +import Data.Flex.Utils (on) + +import Data.Flex.Serial.Wrap () + +{- +import Data.Flex.SmallCheck.Instances +-} + +data X = X + +-- Eq + +prop_default_Eq_is_Eq x y = (x == y) == (w x == w y) where + w = flexiWrap (X :*: TNil) + types = x :: Bool + +prop_explicit_DefaultEq_is_Eq x y = (x == y) == (w x == w y) where + w = flexiWrap (FWDefaultEq :*: TNil) + types = x :: Bool + +prop_TransparentEq_is_Eq x y = (x == y) == (w x == w y) where + w = flexiWrap (FWTransparentEq :*: TNil) + types = x :: Bool + +data FWEqFirst = FWEqFirst + +instance TypeCast r FWEqFirst => FWEq (FW (FWEqFirst :*: s) a) r + +instance Eq a => + Apply (FWEquals t (a, b)) FWEqFirst (FW t (a, b) -> FW t (a, b) -> Bool) + where + apply _ _ = (==) `on` fst . unFlexiWrap + +instance Eq a => + Apply (FWNotEquals t (a, b)) FWEqFirst (FW t (a, b) -> FW t (a, b) -> Bool) + where + apply _ _ = (/=) `on` fst `on` unFlexiWrap + +prop_EqFirst_is_Eq_fst x y = (x `eqFst` y) == (w x == w y) where + eqFst = (==) `on` fst + w = flexiWrap (FWEqFirst :*: TNil) + types = x :: (Bool, Bool) + +testEq :: IO () +testEq = do + smallCheck 1 prop_default_Eq_is_Eq + smallCheck 1 prop_explicit_DefaultEq_is_Eq + smallCheck 1 prop_TransparentEq_is_Eq + smallCheck 1 prop_EqFirst_is_Eq_fst + +-- Ord + +prop_default_Ord_is_Ord x y = (x `compare` y) == (w x `compare` w y) where + w = flexiWrap (X :*: TNil) + types = x :: Bool + +prop_explicit_DefaultOrd_is_Ord x y = (x `compare` y) == (w x `compare` w y) + where + w = flexiWrap (FWDefaultOrd :*: TNil) + types = x :: Bool + +prop_TransparentOrd_is_Ord x y = (x `compare` y) == (w x `compare` w y) where + w = flexiWrap (FWTransparentOrd :*: TNil) + types = x :: Bool + +prop_ReverseOrd_is_reverse_ord x y = (x `compare` y) == (w y `compare` w x) + where + w = flexiWrap (FWReverseOrd :*: TNil) + types = x :: Bool + +testOrd :: IO () +testOrd = do + smallCheck 1 prop_default_Ord_is_Ord + smallCheck 1 prop_explicit_DefaultOrd_is_Ord + smallCheck 1 prop_TransparentOrd_is_Ord + smallCheck 1 prop_ReverseOrd_is_reverse_ord + +-- Show / Read + +prop_default_Show_is_Literal x = show (w x) == "FlexiWrap " ++ show x + where + w = flexiWrap TNil + types = x :: Bool + +prop_default_Read_is_Literal x = read ("FlexiWrap " ++ show x) == w x + where + w = flexiWrap TNil + types = x :: Bool + +prop_explicit_default_Show_is_Literal x = show (w x) == "FlexiWrap " ++ show x + where + w = flexiWrap (FWDefaultShowRead :*: TNil) + types = x :: Bool + +prop_explicit_default_Read_is_Literal x = read ("FlexiWrap " ++ show x) == w x + where + w = flexiWrap (FWDefaultShowRead :*: TNil) + types = x :: Bool + +prop_Literal_Show_is_Literal x = show (w x) == "FlexiWrap " ++ show x + where + w = flexiWrap (FWLiteralShowRead :*: TNil) + types = x :: Bool + +prop_Literal_Read_is_Literal x = read ("FlexiWrap " ++ show x) == w x + where + w = flexiWrap (FWLiteralShowRead :*: TNil) + types = x :: Bool + +prop_Transparent_Show_is_Transparent x = show (w x) == show x + where + w = flexiWrap (FWTransparentShowRead :*: TNil) + types = x :: Bool + +prop_Transparent_Read_is_Transparent x = read (show x) == w x + where + w = flexiWrap (FWTransparentShowRead :*: TNil) + types = x :: Bool + +prop_default_ShowRead_roundtrips x = (read . show) wx == wx + where + wx = flexiWrap TNil x + types = x :: Bool + +prop_LiteralShowRead_roundtrips x = (read . show) wx == wx + where + wx = flexiWrap (FWLiteralShowRead :*: TNil) x + types = x :: Bool + +prop_TransparentShowRead_roundtrips x = (read . show) wx == wx + where + wx = flexiWrap (FWTransparentShowRead :*: TNil) x + types = x :: Bool + +testShowRead :: IO () +testShowRead = do + smallCheck 1 prop_default_Show_is_Literal + smallCheck 1 prop_default_Read_is_Literal + smallCheck 1 prop_explicit_default_Show_is_Literal + smallCheck 1 prop_explicit_default_Read_is_Literal + smallCheck 1 prop_Literal_Show_is_Literal + smallCheck 1 prop_Literal_Read_is_Literal + smallCheck 1 prop_Transparent_Show_is_Transparent + smallCheck 1 prop_Transparent_Read_is_Transparent + smallCheck 1 prop_default_ShowRead_roundtrips + smallCheck 1 prop_LiteralShowRead_roundtrips + smallCheck 1 prop_TransparentShowRead_roundtrips + +-- Monoid + +prop_DefaultMonoid_mempty_is_transparent = mempty == w me + where + w = flexiWrap TNil + me = mempty :: [Bool] + +prop_DefaultMonoid_mappend_is_transparent x y = + w x `mappend` w y == w (x `mappend` y) + where + w = flexiWrap TNil + types = x :: [Bool] + +prop_explicit_DefaultMonoid_mempty_is_transparent = mempty == w me + where + w = flexiWrap (FWDefaultMonoid :*: TNil) + me = mempty :: [Bool] + +prop_explicit_DefaultMonoid_mappend_is_transparent x y = + w x `mappend` w y == w (x `mappend` y) + where + w = flexiWrap (FWDefaultMonoid :*: TNil) + types = x :: [Bool] + +prop_TransparentMonoid_mempty_is_transparent = mempty == w me + where + w = flexiWrap (FWTransparentMonoid :*: TNil) + me = mempty :: [Bool] + +prop_TransparentMonoid_mappend_is_transparent x y = + w x `mappend` w y == w (x `mappend` y) + where + w = flexiWrap (FWTransparentMonoid :*: TNil) + types = x :: [Bool] + +prop_DualMonoid_mempty_is_dual = mempty == w me + where + w = flexiWrap (FWDualMonoid :*: TNil) + me = mempty :: [Bool] + +prop_DualMonoid_mappend_is_dual x y = + w x `mappend` w y == w (y `mappend` x) + where + w = flexiWrap (FWDualMonoid :*: TNil) + types = x :: [Bool] + +f `feq` g = forAll series $ \z -> f z == g z +wfeq = feq `on` unFlexiWrap + +prop_EndoMonoid_mempty_is_id = mempty `wfeq` w idb + where + w = flexiWrap (FWEndoMonoid :*: TNil) + idb = id :: Bool -> Bool + +prop_EndoMonoid_mappend_is_composition x y = + (w x `mappend` w y) `wfeq` w (x . y) + where + w = flexiWrap (FWEndoMonoid :*: TNil) + types = x :: Bool -> Bool + +prop_AllMonoid_mempty_is_True = mempty == w True + where + w = flexiWrap (FWAllMonoid :*: TNil) + +prop_AllMonoid_mappend_is_conjunction x y = + w x `mappend` w y == w (x && y) + where + w = flexiWrap (FWAllMonoid :*: TNil) + types = x :: Bool + +prop_DualAllMonoid_mempty_is_True = mempty == w True + where + w = flexiWrap (FWDualMonoid :*: FWAllMonoid :*: TNil) + +prop_DualAllMonoid_mappend_is_conjunction x y = + w x `mappend` w y == w (x && y) + where + w = flexiWrap (FWDualMonoid :*: FWAllMonoid :*: TNil) + types = x :: Bool + +prop_AnyMonoid_mempty_is_False = mempty == w False + where + w = flexiWrap (FWAnyMonoid :*: TNil) + +prop_AnyMonoid_mappend_is_disjunction x y = + w x `mappend` w y == w (x || y) + where + w = flexiWrap (FWAnyMonoid :*: TNil) + types = x :: Bool + +prop_DualAnyMonoid_mempty_is_False = mempty == w False + where + w = flexiWrap (FWDualMonoid :*: FWAnyMonoid :*: TNil) + +prop_SumMonoid_mempty_is_zero = mempty == w z + where + w = flexiWrap (FWSumMonoid :*: TNil) + z = 0 :: Int + +prop_SumMonoid_mappend_is_addition x y = + w x `mappend` w y == w (x + y) + where + w = flexiWrap (FWSumMonoid :*: TNil) + types = x :: Int + +prop_DualSumMonoid_mempty_is_zero = mempty == w z + where + w = flexiWrap (FWDualMonoid :*: FWSumMonoid :*: TNil) + z = 0 :: Int + +prop_ProductMonoid_mempty_is_one = mempty == w o + where + w = flexiWrap (FWProductMonoid :*: TNil) + o = 1 :: Int + +prop_ProductMonoid_mappend_is_multiplication x y = + w x `mappend` w y == w (x * y) + where + w = flexiWrap (FWProductMonoid :*: TNil) + types = x :: Int + +prop_DualProductMonoid_mappend_is_multiplication x y = + w x `mappend` w y == w (x * y) + where + w = flexiWrap (FWDualMonoid :*: FWProductMonoid :*: TNil) + types = x :: Int + +prop_FirstMonoid_mempty_is_Nothing = mempty == w n + where + w = flexiWrap (FWFirstMonoid :*: TNil) + n = Nothing :: Maybe Bool + +prop_FirstMonoid_mempty_mappend_is_id x = + mempty `mappend` x == x + where + types = x :: FW (FWFirstMonoid :*: TNil) (Maybe Bool) + +prop_FirstMonoid_Just_mappend_is_const x y = + wx `mappend` y == wx + where + w = flexiWrap (FWFirstMonoid :*: TNil) + wx = w $ Just x + types = (x :: Bool, y :: FW (FWFirstMonoid :*: TNil) (Maybe Bool)) + +prop_LastMonoid_mempty_is_Nothing = mempty == w n + where + w = flexiWrap (FWLastMonoid :*: TNil) + n = Nothing :: Maybe Bool + +prop_LastMonoid_mappend_mempty_is_id x = + x `mappend` mempty == x + where + types = x :: FW (FWLastMonoid :*: TNil) (Maybe Bool) + +prop_LastMonoid_mappend_Just_is_const x y = + y `mappend` wx == wx + where + w = flexiWrap (FWLastMonoid :*: TNil) + wx = w $ Just x + types = (x :: Bool, y :: FW (FWLastMonoid :*: TNil) (Maybe Bool)) + +prop_DualFirstMonoid_mappend_is_Last x y = + wdf x `mappend` wdf y `uweq` wl x `mappend` wl y + where + wdf = flexiWrap (FWDualMonoid :*: FWFirstMonoid :*: TNil) + wl = flexiWrap (FWLastMonoid :*: TNil) + infix 4 `uweq` + uweq u v = unFlexiWrap u == unFlexiWrap v + types = (x :: Maybe Bool, y :: Maybe Bool) + +testMonoid :: IO () +testMonoid = do + smallCheck 0 prop_DefaultMonoid_mempty_is_transparent + smallCheck 1 prop_DefaultMonoid_mappend_is_transparent + smallCheck 0 prop_explicit_DefaultMonoid_mempty_is_transparent + smallCheck 1 prop_explicit_DefaultMonoid_mappend_is_transparent + smallCheck 0 prop_TransparentMonoid_mempty_is_transparent + smallCheck 1 prop_TransparentMonoid_mappend_is_transparent + smallCheck 0 prop_DualMonoid_mempty_is_dual + smallCheck 1 prop_DualMonoid_mappend_is_dual + smallCheck 0 prop_EndoMonoid_mempty_is_id + smallCheck 1 prop_EndoMonoid_mappend_is_composition + smallCheck 0 prop_AllMonoid_mempty_is_True + smallCheck 1 prop_AllMonoid_mappend_is_conjunction + smallCheck 0 prop_DualAllMonoid_mempty_is_True + smallCheck 1 prop_DualAllMonoid_mappend_is_conjunction + smallCheck 0 prop_AnyMonoid_mempty_is_False + smallCheck 1 prop_AnyMonoid_mappend_is_disjunction + smallCheck 0 prop_DualAnyMonoid_mempty_is_False + smallCheck 0 prop_SumMonoid_mempty_is_zero + smallCheck 1 prop_SumMonoid_mappend_is_addition + smallCheck 0 prop_DualSumMonoid_mempty_is_zero + smallCheck 0 prop_ProductMonoid_mempty_is_one + smallCheck 1 prop_ProductMonoid_mappend_is_multiplication + smallCheck 1 prop_DualProductMonoid_mappend_is_multiplication + smallCheck 0 prop_FirstMonoid_mempty_is_Nothing + smallCheck 1 prop_FirstMonoid_mempty_mappend_is_id + smallCheck 1 prop_FirstMonoid_Just_mappend_is_const + smallCheck 0 prop_LastMonoid_mempty_is_Nothing + smallCheck 1 prop_LastMonoid_mappend_mempty_is_id + smallCheck 1 prop_LastMonoid_mappend_Just_is_const + smallCheck 1 prop_DualFirstMonoid_mappend_is_Last + +testAll :: IO () +testAll = do + testEq + testOrd + testShowRead + testMonoid + +-- vim: expandtab:tabstop=4:shiftwidth=4