natural-transformation-0.4/0000755000000000000000000000000013012664221014252 5ustar0000000000000000natural-transformation-0.4/CHANGELOG.md0000644000000000000000000000077113012664221016070 0ustar0000000000000000# 0.4 * Rename `Nat` constructor to `NT` * Rename `run` to `unwrapNT` * Rename `nat` to `wrapNT` * Backport the `Semigroup` instance for `(:~>)` by conditionally depending on the `semigroups` package # 0.3.1 * Adding `run` and `nat`. # 0.3 * Adding Object * Rolled Control.Transformation into Control.Natural * Added RULES module * Required GHC 7.8 or greater * `Semigroup` instance for `(:~>)` on GHC 8.0 and up # 0.2 * Require GHC 7.6 or greater * Exposed `~>` type synonym # 0.1 * Initial commit natural-transformation-0.4/README.md0000644000000000000000000000107213012664221015531 0ustar0000000000000000# natural-transformation [![Hackage version](https://img.shields.io/hackage/v/natural-transformation.svg?style=flat)](http://hackage.haskell.org/package/natural-transformation) [![Build Status](https://img.shields.io/travis/ku-fpg/natural-transformation.svg?style=flat)](https://travis-ci.org/ku-fpg/natural-transformation) A natural transformation transforms a container `f a` into another container `g a`. Natural transformations act as functor morphisms in category theory. Technically, `f` and `g` should be functors, but we allow any correctly-shaped structure. natural-transformation-0.4/natural-transformation.cabal0000644000000000000000000000413213012664221021750 0ustar0000000000000000name: natural-transformation version: 0.4 synopsis: A natural transformation package. description: A natural transformation transforms a container @f a@ into another container @g a@. Natural transformations act as functor morphisms in category theory. . The naming of '~>', ':~>' and '$$' were taken, with permission, from Edward Kmett's @indexed@ package. 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 copyright: Copyright (c) 2015-2016 The University of Kansas category: Control build-type: Simple extra-source-files: CHANGELOG.md, README.md tested-with: GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1 cabal-version: >= 1.10 source-repository head type: git location: https://github.com/ku-fpg/natural-transformation library exposed-modules: Control.Natural Control.Natural.RULES Control.Object build-depends: base >= 4.7 && < 5 if !impl(ghc >= 8.0) build-depends: semigroups >= 0.16 && < 0.19 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.7 && < 5 , containers >= 0.1 && < 0.6 , natural-transformation == 0.4 , quickcheck-instances >= 0.1 && < 0.4 , tasty >= 0.8 && < 0.12 , tasty-quickcheck >= 0.8 && < 0.9 hs-source-dirs: tests default-language: Haskell2010 ghc-options: -Wall natural-transformation-0.4/LICENSE0000644000000000000000000000301713012664221015260 0ustar0000000000000000Copyright (c) 2015-2016, 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. natural-transformation-0.4/Setup.hs0000644000000000000000000000005613012664221015707 0ustar0000000000000000import Distribution.Simple main = defaultMain natural-transformation-0.4/src/0000755000000000000000000000000013012664221015041 5ustar0000000000000000natural-transformation-0.4/src/Control/0000755000000000000000000000000013012664221016461 5ustar0000000000000000natural-transformation-0.4/src/Control/Object.hs0000644000000000000000000000123613012664221020225 0ustar0000000000000000{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE Safe #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE RankNTypes #-} {-| Module: Control.Object Copyright: (C) 2015 The University of Kansas License: BSD-style (see the file LICENSE) Maintainer: Andy Gill Stability: Experimental An Object type, which is a natural transformation into the 'IO' monad. -} module Control.Object (Object(..), (#)) where import Control.Natural -- | An 'Object' is a natural transformation from a given 'Functor' 'f', to 'IO'. newtype Object f = Object (f ~> IO) instance Transformation f IO (Object f) where Object f # g = NT f # g natural-transformation-0.4/src/Control/Natural.hs0000644000000000000000000000524013012664221020424 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE Safe #-} {-# LANGUAGE TypeOperators #-} {-| 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 and class for natural transformations. -} module Control.Natural ( -- * Newtype for a Natural Transformation (:~>)(..) -- * Type Synonym for a Natural Transformation , type (~>) -- * Conversion functions between the newtype and the synonym , wrapNT , unwrapNT -- * Class for Natural Transformations , Transformation(..) ) where import qualified Control.Category as C (Category(..)) #if !(MIN_VERSION_base(4,8,0)) import Data.Monoid (Monoid(..)) #endif import Data.Semigroup (Semigroup(..)) import Data.Typeable --------------------------------------------------------------------------- -- Naming of ~>, :~> and $$ are taken (with permission) from Edward Kmett's @indexed@ package. --------------------------------------------------------------------------- infixr 0 ~> -- | A natural transformation from @f@ to @g@. type f ~> g = forall x. f x -> g x infixr 0 :~>, $$ -- | A natural transformation suitable for storing in a container. newtype f :~> g = NT { ($$) :: f ~> g } deriving Typeable instance C.Category (:~>) where id = NT id NT f . NT g = NT (f . g) instance f ~ g => Semigroup (f :~> g) where NT f <> NT g = NT (f . g) instance f ~ g => Monoid (f :~> g) where mempty = NT id mappend = (<>) infix 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 ':~>', 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 -> forall a . f a -> g a instance Transformation f g (f :~> g) where NT f # g = f g -- | 'wrapNT' builds our natural transformation abstraction out of -- a natural transformation function. -- -- An alias to 'NT' provided for symmetry with 'unwrapNT'. -- wrapNT :: (forall a . f a -> g a) -> f :~> g wrapNT = NT -- | 'unwrapNT' is the nonfix version of @#@. It is used to break natural -- transformation wrappers, including ':~>'. unwrapNT :: Transformation f g t => t -> (forall a . f a -> g a) unwrapNT = (#) natural-transformation-0.4/src/Control/Natural/0000755000000000000000000000000013012664221020067 5ustar0000000000000000natural-transformation-0.4/src/Control/Natural/RULES.hs0000644000000000000000000000141213012664221021313 0ustar0000000000000000{-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE Trustworthy #-} {-# OPTIONS_GHC -fno-warn-orphans #-} {-| Module: Control.Transformation.RULES Copyright: (C) 2015 The University of Kansas License: BSD-style (see the file LICENSE) Maintainer: Andy Gill Stability: Experimental = GHC RULE for Natural Transformation @ RULES "natural free theorem" [~] forall h (r :: (Functor f, Functor g, Transformation f g t) => t) . fmap h . (r \#) = (r #) . fmap h @ -} module Control.Natural.RULES () where import Control.Natural {-# RULES "natural free theorem" [~] forall h (r :: (Functor f, Functor g, Transformation f g t) => t) . fmap h . (r #) = (r #) . fmap h #-} natural-transformation-0.4/tests/0000755000000000000000000000000013012664221015414 5ustar0000000000000000natural-transformation-0.4/tests/Properties.hs0000644000000000000000000000471713012664221020115 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE 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 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 = NT reverse -- | A natural transformation from lists to lists that shifts all elements to the left, -- moving the head element to the back. listShiftNT :: [] :~> [] listShiftNT = NT $ \l -> case l of [] -> [] (x:xs) -> xs ++ [x] -- | A natural transformation from lists to 'Seq's. listSeqNT :: [] :~> Seq listSeqNT = NT fromList -- | A natural transformation from 'Seq's to lists. seqListNT :: Seq :~> [] seqListNT = NT toList