natural-transformation (empty) → 0.1
raw patch · 8 files changed
+266/−0 lines, 8 filesdep +basedep +containersdep +natural-transformationsetup-changed
Dependencies added: base, containers, natural-transformation, quickcheck-instances, tasty, tasty-quickcheck
Files
- CHANGELOG.md +2/−0
- LICENSE +30/−0
- README.md +3/−0
- Setup.hs +2/−0
- natural-transformation.cabal +43/−0
- src/Control/Natural.hs +73/−0
- src/Control/Transformation.hs +37/−0
- tests/Properties.hs +76/−0
+ CHANGELOG.md view
@@ -0,0 +1,2 @@+# 0.1+* Initial commit
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2015, The University of Kansas++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of The University of Kansas nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,3 @@+# natural-transformation [](http://hackage.haskell.org/package/natural-transformation) [](https://travis-ci.org/ku-fpg/natural-transformation)++A natural transformation transforms a container `f a` into another container `g a` while preserving the internal structure. Natural transformations act as functor morphisms in category theory. Technically, `f` and `g` should be functors, but we allow any correctly-shaped structure.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ natural-transformation.cabal view
@@ -0,0 +1,43 @@+name: natural-transformation+version: 0.1+synopsis: A natural transformation package.+description: A natural transformation transforms a container @f a@ into another+ container @g a@ while preserving the internal structure. Natural+ transformations act as functor morphisms in category theory.+homepage: https://github.com/ku-fpg/natural-transformation+bug-reports: https://github.com/ku-fpg/natural-transformation/issues+license: BSD3+license-file: LICENSE+stability: Provisional+author: Andy Gill+maintainer: Andy Gill <andygill@ku.edu>+copyright: Copyright (c) 2015 The University of Kansas+category: Control+build-type: Simple+extra-source-files: CHANGELOG.md, README.md+cabal-version: >= 1.10++source-repository head+ type: git+ location: git://github.com/ku-fpg/natural-transformation++library+ exposed-modules: Control.Natural+ Control.Transformation+ build-depends: base >= 3 && < 5+ hs-source-dirs: src+ default-language: Haskell2010+ ghc-options: -Wall++test-suite natural-transformation-properties+ type: exitcode-stdio-1.0+ main-is: Properties.hs+ build-depends: base >= 4.5 && < 5+ , containers >= 0.1 && < 0.6+ , natural-transformation == 0.1+ , quickcheck-instances >= 0.1 && < 0.4+ , tasty >= 0.8 && < 0.11+ , tasty-quickcheck >= 0.8 && < 0.9+ hs-source-dirs: tests+ default-language: Haskell2010+ ghc-options: -Wall
+ src/Control/Natural.hs view
@@ -0,0 +1,73 @@+{-# LANGUAGE CPP, FlexibleInstances, RankNTypes, TypeFamilies, TypeOperators #-}++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 706 && MIN_VERSION_base(4,7,0)+# define LANGUAGE_PolyKinds+{-# LANGUAGE PolyKinds #-}+#endif++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708+# define LANGUAGE_DeriveDataTypeable+{-# LANGUAGE DeriveDataTypeable #-}+#else+{-# LANGUAGE ScopedTypeVariables #-}+#endif++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702+# if defined(LANGUAGE_DeriveDataTypeable)+{-# LANGUAGE Safe #-}+# else+{-# LANGUAGE Trustworthy #-}+# endif+#endif++{-|+Module: Control.Natural+Copyright: (C) 2015 The University of Kansas+License: BSD-style (see the file LICENSE)+Maintainer: Andy Gill+Stability: Experimental++A data type for natural transformations.+-}+module Control.Natural ((:~>)(..)) where++#if defined(LANGUAGE_PolyKinds)+import qualified Control.Category as C (Category(..))+#endif++#if !(MIN_VERSION_base(4,8,0))+import Data.Monoid (Monoid(..))+#endif+import Data.Typeable++---------------------------------------------------------------------------+-- Code adapted, with permission, from Edward Kmett's @indexed@ package.+---------------------------------------------------------------------------++infixr 0 :~>, $$+-- | A natural transformation from @f@ to @g@.+newtype f :~> g = Nat { ($$) :: forall x. f x -> g x }+#if defined(LANGUAGE_DeriveDataTypeable)+ deriving Typeable+#else+instance (Typeable1 f, Typeable1 g) => Typeable (f :~> g) where+ typeOf _ = mkTyConApp natTyCon [typeOf1 (undefined :: f a), typeOf1 (undefined :: g a)]++natTyCon :: TyCon+# if MIN_VERSION_base(4,4,0)+natTyCon = mkTyCon3 "natural-transformation" "Control.Natural" ":~>"+# else+natTyCon = mkTyCon ":~>"+# endif+{-# NOINLINE natTyCon #-}+#endif++#if defined(LANGUAGE_PolyKinds)+instance C.Category (:~>) where+ id = Nat id+ Nat f . Nat g = Nat (f . g)+#endif++instance f ~ g => Monoid (f :~> g) where+ mempty = Nat id+ mappend (Nat f) (Nat g) = Nat (f . g)
+ src/Control/Transformation.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE CPP, FlexibleInstances, FunctionalDependencies,+ MultiParamTypeClasses, TypeOperators #-}++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 706 && MIN_VERSION_base(4,7,0)+{-# LANGUAGE PolyKinds #-}+#endif++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702+{-# LANGUAGE Safe #-}+#endif++{-|+Module: Control.Transformation+Copyright: (C) 2015 The University of Kansas+License: BSD-style (see the file LICENSE)+Maintainer: Andy Gill+Stability: Experimental++A type class for transformations.+-}+module Control.Transformation (Transformation(..)) where++import Control.Natural ((:~>)(..))++infixr 0 #+-- | A (natural) transformation is inside @t@, and contains @f@ and @g@+-- (typically 'Functor's).+-- +-- The order of arguments allows the use of @GeneralizedNewtypeDeriving@ to wrap+-- a 'Natural', but maintain the 'Transformation' constraint. Thus, '#' can be used+-- on abstract data types.+class Transformation f g t | t -> f g where+ -- | The invocation method for a natural transformation.+ (#) :: t -> f a -> g a++instance Transformation f g (f :~> g) where+ Nat f # g = f g
+ tests/Properties.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE CPP, TypeOperators #-}+{-|+Module: Main+Copyright: (C) 2015 The University of Kansas+License: BSD-style (see the file LICENSE)+Maintainer: Andy Gill+Stability: Experimental++@QuickCheck@ properties for natural transformations.+-}+module Main (main) where++import Control.Natural ((:~>)(..))+import Control.Transformation (Transformation(..))++import Data.Foldable (toList)+#if !(MIN_VERSION_base(4,8,0))+import Data.Monoid (Monoid(..))+#endif+import Data.Sequence (Seq, fromList)++import Test.QuickCheck.Instances ()+import Test.Tasty (TestTree, defaultMain, testGroup)+import Test.Tasty.QuickCheck (testProperty)++main :: IO ()+main = defaultMain testProperties++testProperties :: TestTree+testProperties = testGroup "QuickCheck properties"+ [ testProperty "Free theorem ([] :~> Seq)" (prop_freeTheorem (+1) listSeqNT :: [Int] -> Bool)+ , testProperty "Free theorem (Seq :~> [])" (prop_freeTheorem reverse seqListNT :: Seq String -> Bool)+ , testProperty "Monoid laws" (prop_monoidLaws listShiftNT listReverseNT listShiftNT :: [Int] -> Bool)+ ]++-- | Verifies the free theorem for natural transformations, i.e., that+-- +-- @+-- fmap h . r == r . fmap h+-- @+prop_freeTheorem :: (Eq (g b), Functor f, Functor g, Transformation f g t)+ => (a -> b) -> t -> f a -> Bool+prop_freeTheorem h r t = fmap h (r # t) == (r # fmap h t)++-- | Verifies that natural transformations form a law-abiding 'Monoid', i.e., that+-- +-- * @mappend mempty x = x@+--+-- * @mappend x mempty = x@+--+-- * @mappend x (mappend y z) = mappend (mappend x y) z@+prop_monoidLaws :: (Eq (f a), Monoid t, Transformation f f t)+ => t -> t -> t -> f a -> Bool+prop_monoidLaws x y z t = (mappend mempty x # t) == (x # t)+ && (mappend x mempty # t) == (x # t)+ && (mappend x (mappend y z) # t)+ == (mappend (mappend x y) z # t)++-- | A natural transformations from lists to lists that 'reverse's.+listReverseNT :: [] :~> []+listReverseNT = Nat reverse++-- | A natural transformation from lists to lists that shifts all elements to the left,+-- moving the head element to the back.+listShiftNT :: [] :~> []+listShiftNT = Nat $ \l -> case l of+ [] -> []+ (x:xs) -> xs ++ [x]++-- | A natural transformation from lists to 'Seq's.+listSeqNT :: [] :~> Seq+listSeqNT = Nat fromList++-- | A natural transformation from 'Seq's to lists.+seqListNT :: Seq :~> []+seqListNT = Nat toList