packages feed

data-foldapp (empty) → 0.1.0.0

raw patch · 8 files changed

+652/−0 lines, 8 filesdep +basedep +containerssetup-changed

Dependencies added: base, containers

Files

+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Revision history for data-foldapp
+
+## 0.1.0.0  -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
+ Data/FoldApp.hs view
@@ -0,0 +1,56 @@+-- | This package provides a framework for constructing variadic+--   functions as folds over function applications.+--+--   For example, a variadic function @f@ may be reduced like this:+--+-- @+-- f a b c+-- ≡ foldlApp @(~) f' z a b c+-- ≡ f' (f' (f' z a) b) c+-- @+--+--   Both left and right associative folds are available.+--+--   This module re-exports "Data.FoldApp.Identity" which assumes the+--   identity conversion for arguments. "Data.FoldApp.Generic" provides+--   the generalised folds where a different converter may be given.+--   Conversion allows for folding over differently-typed arguments by+--   converting them to a common type.+--+--   "Data.FoldApp.Function" contains several variadic functions which+--   may be useful as examples or in your programs.+--+--   Folds cannot be defined to return functions. This is because the+--   parameters intended for the returned function become confused with+--   the parameters intended for folding. This weakness can be+--   circumvented by wrapping and unwrapping returned functions with+--   a newtype at the cost of inconvenience.+--+--   If a type inference problem arises, you possibly need to provide+--   an annotation for some arguments or an annotation for the return+--   type. For example, without any other typing context the following+--   is ambiguous …+--+-- @+-- listOf "hello" "sailor!"+-- @+--+--   … because it is not known how many more arguments should be+--   accepted. An annotation such as the following fixes this problem …+--+-- @+-- listOf "hello" "sailor!" :: String -> [String]+-- @+--+--   … saying one more @String@ argument must be given and a @[String]@+--   will be returned.+--+module Data.FoldApp+  ( module Data.FoldApp.Function+  , module Data.FoldApp.Identity+  )+where++import Data.FoldApp.Function++import Data.FoldApp.Identity
+ Data/FoldApp/Function.hs view
@@ -0,0 +1,302 @@+-- | Module of variadic functions.+--+--   All types used are re-exported.+--+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Data.FoldApp.Function+  ( Alternative+  , Bool+  , FoldlApp+  , FoldrApp+  , IntMap+  , IntSet+  , Map+  , MonadPlus+  , Monoid+  , NonEmpty+  , Num+  , Ord+  , Ordering+  , Seq+  , Set+  , allOf+  , allOfBy+  , asumOf+  , dualAsumOf+  , dualFoldOf+  , dualMsumOf+  , firstOf+  , foldOf+  , intSetOf+  , lastOf+  , lazyIntMapOf+  , lazyMapOf+  , listOf+  , maxOf+  , maxOfBy+  , minOf+  , minOfBy+  , msumOf+  , nonEmptyOf+  , productOf+  , reverseNonEmptyOf+  , reverseOf+  , reverseSeqOf+  , seqOf+  , setOf+  , strictIntMapOf+  , strictMapOf+  , sumOf+  )+where++import Control.Applicative+  ( Alternative(empty, (<|>))+  )+--++import Control.Monad+  ( MonadPlus(mzero, mplus)+  )+--++import Data.Bool+  ( Bool(True, False)+  , (||)+  , (&&)+  )+--++import Data.FoldApp.Identity+  ( FoldlApp+  , FoldrApp+  , foldlApp+  , foldrApp+  )+--++import Data.IntMap (IntMap)+import qualified Data.IntMap.Lazy as LazyIntMap+import qualified Data.IntMap.Strict as StrictIntMap++import Data.IntSet (IntSet)+import qualified Data.IntSet as IntSet++import Data.List.NonEmpty(NonEmpty((:|)))+import qualified Data.List.NonEmpty as NonEmpty++import Data.Map (Map)+import qualified Data.Map.Lazy as LazyMap+import qualified Data.Map.Strict as StrictMap++import Data.Monoid+  ( Monoid(mempty, mappend)+  )+--++import Data.Ord+  ( Ord+  , Ordering(LT, EQ, GT)+  )+--++import Data.Sequence (Seq)+import qualified Data.Sequence as Seq++import Data.Set(Set)+import qualified Data.Set as Set++import Prelude+  ( Num((+), (*))+  , (.)+  , flip+  , max+  , min+  , uncurry+  )+--++-- | True if all arguments are True, False otherwise.+--+allOf :: FoldrApp Bool Bool f => f+allOf = foldrApp (&&) True++-- | True if all arguments map to True, False otherwise.+--+allOfBy :: FoldlApp a Bool f => (a -> Bool) -> f+allOfBy f = foldlApp (\a x -> a && f x) True++-- | True if any arguments are True, False otherwise.+--+anyOf :: FoldrApp Bool Bool f => f+anyOf = foldrApp (||) False++-- | True if any arguments map to True, False otherwise.+--+anyOfBy :: FoldlApp a Bool f => (a -> Bool) -> f+anyOfBy f = foldlApp (\a x -> a || f x) False++-- | Concatentate all arguments with @\<|\>@.+--+asumOf :: forall a f g. (Alternative f, FoldrApp (f a) (f a) g) => g+asumOf = foldrApp (<|>) (empty :: f a)++-- | Concatenate all arguments with @\<|\>@ in reverse order.+--+dualAsumOf :: forall a f g. (Alternative f, FoldrApp (f a) (f a) g) => g+dualAsumOf = foldrApp (flip (<|>)) (empty :: f a)++-- | Concatenate all argments with @mappend@ in reverse order.+--+dualFoldOf :: forall a f. (Monoid a, FoldlApp a a f) => f+dualFoldOf = foldlApp (flip mappend) (mempty :: a)++-- | Concatenate all arguments with @mplus@ in reverse order.+--+dualMsumOf :: forall a m f. (MonadPlus m, FoldrApp (m a) (m a) f) => f+dualMsumOf = foldrApp (flip mplus) (mzero :: m a)++-- | Returns the first argument.+--+firstOf :: forall a f. FoldlApp a a f => a -> f+firstOf = foldlApp ((\x _ -> x) :: a -> a -> a)++-- | Concatenate all arguments with @mappend@.+--+foldOf :: forall a f. (Monoid a, FoldrApp a a f) => f+foldOf = foldrApp mappend (mempty :: a)++-- | Form an @IntSet@ from all arguments.+--+intSetOf :: forall f. FoldlApp IntSet.Key IntSet f => f+intSetOf = foldlApp (flip IntSet.insert) IntSet.empty++-- | Returns the last argument.+--+lastOf :: forall a f. FoldlApp a a f => a -> f+lastOf = foldlApp (\_ y -> y)++-- | Form a lazy @IntMap@ from all arguments.+--+lazyIntMapOf ::+  forall a f.+  FoldlApp (StrictIntMap.Key, a) (IntMap a) f =>+  f+lazyIntMapOf =+  foldlApp+  (flip (uncurry LazyIntMap.insert))+  (LazyIntMap.empty :: IntMap a)+--++-- | Form a lazy @Map@ from all arguments.+--+lazyMapOf :: forall k a f. (Ord k, FoldlApp (k, a) (Map k a) f) => f+lazyMapOf =+  foldlApp+  (flip (uncurry LazyMap.insert))+  (LazyMap.empty :: Map k a)+--++-- | Form a list from all arguments.+--+listOf :: forall a f. FoldrApp a [a] f => f+listOf = foldrApp (:) ([] :: [a])++-- | Return the largest argument.+--+maxOf :: forall a f. (Ord a, FoldlApp a a f) => a -> f+maxOf = foldlApp max++-- | Return the largest argument by the given comparator.+--+maxOfBy ::+  forall a f.+  (Ord a, FoldlApp a a f) =>+  (a -> a -> Ordering) -> a -> f+maxOfBy f = foldlApp (\a x -> case f a x of GT -> a; _ -> x)++-- | Return the smallest argument.+--+minOf :: forall a f. (Ord a, FoldlApp a a f) => a -> f+minOf = foldlApp min++-- | Return the smallest argument by the given comparator.+--+minOfBy ::+  forall a f.+  (Ord a, FoldlApp a a f) =>+  (a -> a -> Ordering) -> a -> f+minOfBy f = foldlApp (\a x -> case f a x of GT -> x; _ -> a)++-- | Concatentate all arguments with @mplus@.+--+msumOf :: forall a m f. (MonadPlus m, FoldrApp (m a) (m a) f) => f+msumOf = foldrApp mplus (mzero :: m a)++-- | Form a @NonEmpty@ list from all arguments.+--+nonEmptyOf :: FoldrApp a (NonEmpty a) f => a -> f+nonEmptyOf = foldrApp (\a (x:|xs) -> x:|(a:xs)) . (:|[])++-- | Return the product of all arguments.+--+productOf :: forall a f. (Num a, FoldlApp a a f) => f+productOf = foldlApp (*) (1 :: a)++-- | Form a @NonEmpty@ list in reverse order from all arguments.+--+reverseNonEmptyOf :: FoldlApp a (NonEmpty a) f => a -> f+reverseNonEmptyOf = foldlApp (\(x:|xs) a -> a:|(x:xs)) . (:|[])++-- | Form a list in reverse order from all arguments.+--+reverseOf :: forall a f. FoldlApp a [a] f => f+reverseOf = foldlApp (flip (:)) ([] :: [a])++-- | Form a @Seq@ from all arguments.+--+seqOf :: forall a f. FoldlApp a (Seq a) f => f+seqOf = foldlApp (Seq.|>) (Seq.empty :: Seq a)++-- | Form a @Seq@ in reverse order from all arguments.+--+reverseSeqOf :: forall a f. FoldlApp a (Seq a) f => f+reverseSeqOf = foldlApp (flip (Seq.<|)) (Seq.empty :: Seq a)++-- | Form a @Set@ from all arguments.+--+setOf :: forall a f. (Ord a, FoldlApp a (Set a) f) => f+setOf = foldlApp (flip Set.insert) (Set.empty :: Set a)++-- | Form a strict @IntMap@ from all arguments.+--+strictIntMapOf ::+  forall a f.+  FoldlApp (StrictIntMap.Key, a) (IntMap a) f =>+  f+strictIntMapOf =+  foldlApp+  (flip (uncurry StrictIntMap.insert))+  (StrictIntMap.empty :: IntMap a)+--++-- | Form a strict @Map@ from all arguments.+--+strictMapOf ::+  forall k a f.+  (Ord k, FoldlApp (k, a) (Map k a) f) =>+  f+strictMapOf =+  foldlApp+  (flip (uncurry StrictMap.insert))+  (StrictMap.empty :: Map k a)+--++-- | Return the sum of all arguments.+--+sumOf :: forall a f. (Num a, FoldlApp a a f) => f+sumOf = foldlApp (+) (0 :: a)
+ Data/FoldApp/Generic.hs view
@@ -0,0 +1,152 @@+-- | The most generic definitions for folding function applications.+--+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+module Data.FoldApp.Generic+  ( Converter(convert)+  , FoldlApp(foldlApp)+  , FoldrApp()+  , Monad+  , foldlMApp+  , foldrApp+  , foldrMApp+  )+where++import Control.Monad+  ( Monad((>>=), return)+  )+--++import Data.Kind+  ( Constraint+  )+--++import Prelude+  ( id+  , flip+  )+--++-- | Class of constraints which feature a function to convert a value of+--   one type to a value of another.+--+class Converter (conv :: * -> * -> Constraint) where+  convert :: conv a b => a -> b+--++instance Converter (~) where+  convert = id+--++-- | Constrain all parameters of f to be convertible to p and the return+--   of f to be r.+--+type family+  Infer (conv :: * -> * -> Constraint)+        (p    :: *                   )+        (r    :: *                   )+        (f    :: *                   )+        :: Constraint+  where+  Infer conv p r (a -> f) = (conv a p, Infer conv p r f)+  Infer _    _ r s        = r ~ s+--++-- | Class defining left-associative folds of function applications. No+--   other instances need be defined.+--+class+  ( Converter conv+  , Infer conv p r f+  ) =>+  FoldlApp (conv :: * -> * -> Constraint)+           (p    :: *                   )+           (r    :: *                   )+           (f    :: *                   )+  where+  -- | Left-associative fold of function applications.+  foldlApp :: (r -> p -> r) -> r -> f+--++instance (Converter conv, Infer conv p r r) => FoldlApp conv p r r where+  foldlApp _ r = r+--++instance+  ( Converter conv+  , Infer conv p r (x -> f)+  , FoldlApp conv p r f+  ) =>+  FoldlApp conv p r (x -> f)+  where+  foldlApp f r p = foldlApp @conv f (f r (convert @conv p))+--++-- | Monadic left-associative fold of function applications.+--+foldlMApp ::+  forall conv m p r f.+  (Monad m, FoldlApp conv p (m r) f) =>+  (r -> p -> m r) -> r -> f+foldlMApp f r = foldlApp @conv (\r' p -> r' >>= flip f p) (return r)++-- | Class defining right-associative folds of function applications. No+--   other instances need be defined.+--+class+  ( Converter conv+  , Infer conv p r f+  ) =>+  FoldrApp (conv :: * -> * -> Constraint)+           (p    :: *                   )+           (r    :: *                   )+           (f    :: *                   )+  where+  -- | Right-associative fold of function applications. This is an+  --   internal implementation; use 'foldrApp' instead.+  foldrAppImpl :: (p -> r -> r) -> (r -> r) -> r -> f+--++instance (Converter conv, Infer conv p r r) => FoldrApp conv p r r where+  foldrAppImpl _ g r = g r+--++instance+ ( Converter conv+ , Infer conv p r (x -> f)+ , FoldrApp conv p r f+ ) => FoldrApp conv p r (x -> f)+ where+  foldrAppImpl f g r p =+    foldrAppImpl @conv f (\r' -> g (f (convert @conv p) r')) r+--++-- | Right-associative fold of function applications.+--+foldrApp ::+  forall conv p r f.+  FoldrApp conv p r f =>+  (p -> r -> r) -> r -> f+foldrApp f = foldrAppImpl @conv f id++-- | Monadic right-associative fold of function applications.+--+foldrMApp ::+  forall conv m p r f.+  (Monad m, FoldrApp conv p (m r) f) =>+  (p -> r -> m r) -> r -> f+foldrMApp f r = foldrApp @conv (\p r' -> r' >>= f p) (return r)
+ Data/FoldApp/Identity.hs view
@@ -0,0 +1,65 @@+-- | Specialised functions for folds of function applications. The+--   converter has been specialised to the identity converter.+--+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeApplications #-}+module Data.FoldApp.Identity+  ( FoldlApp+  , FoldrApp+  , foldlApp+  , foldlMApp+  , foldrApp+  , foldrMApp+  , Monad+  )+where++import Control.Monad+  ( Monad+  )+--++import qualified Data.FoldApp.Generic as G++-- | @Data.FoldApp.FoldlApp@ with the identity converter chosen.+--+type FoldlApp p r f = G.FoldlApp (~) p r f++-- | @Data.FoldApp.FoldrAPp@ with the identity converter chosen.+--+type FoldrApp p r f = G.FoldrApp (~) p r f++-- | Left-associative fold of function applications.+--+foldlApp ::+  forall p r f.+  (FoldlApp p r f) =>+  (r -> p -> r) -> r -> f+foldlApp = G.foldlApp @(~)++-- | Monadic left-associative fold of function applications.+--+foldlMApp ::+  forall m p r f.+  (Monad m, FoldlApp p (m r) f) =>+  (r -> p -> m r) -> r -> f+foldlMApp = G.foldlMApp @(~)++-- | Right-associative fold of function applications.+--+foldrApp ::+  forall p r f.+  FoldrApp p r f =>+  (p -> r -> r) -> r -> f+foldrApp = G.foldrApp @(~)++-- | Monadic right-associative fold of function applications.+--+foldrMApp ::+  forall m p r f.+  (Monad m, FoldrApp p (m r) f) =>+  (p -> r -> m r) -> r -> f+foldrMApp = G.foldrMApp @(~)
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2017, Eric Brisco
+
+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 Eric Brisco 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple
+main = defaultMain
+ data-foldapp.cabal view
@@ -0,0 +1,40 @@+name:                data-foldapp
+version:             0.1.0.0
+synopsis:            Fold function applications. Framework for variadic functions.
+description:         Fold function applications. Framework for variadic functions.
+homepage:            https://github.com/erisco/data-foldapp
+license:             BSD3
+license-file:        LICENSE
+author:              Eric Brisco
+maintainer:          eric.brisco@gmail.com
+copyright:           Copyright (c) 2017, Eric Brisco
+category:            Data
+build-type:          Simple
+extra-source-files:  ChangeLog.md
+cabal-version:       >=1.10
+
+
+
+source-repository head
+  type:     git
+  location: https://github.com/erisco/data-foldapp
+
+
+
+source-repository this
+  type:     git
+  location: https://github.com/erisco/data-foldapp
+  tag:      v0.1.0.0
+
+  
+
+library
+  exposed-modules:    Data.FoldApp
+                    , Data.FoldApp.Generic
+                    , Data.FoldApp.Identity
+                    , Data.FoldApp.Function
+  
+  build-depends:      base >=4.9 && <4.10
+                    , containers >=0.5 && <0.6
+  
+  default-language:   Haskell2010