diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Revision history for data-foldapp
+
+## 0.1.0.0  -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/Data/FoldApp.hs b/Data/FoldApp.hs
new file mode 100644
--- /dev/null
+++ b/Data/FoldApp.hs
@@ -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
diff --git a/Data/FoldApp/Function.hs b/Data/FoldApp/Function.hs
new file mode 100644
--- /dev/null
+++ b/Data/FoldApp/Function.hs
@@ -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)
diff --git a/Data/FoldApp/Generic.hs b/Data/FoldApp/Generic.hs
new file mode 100644
--- /dev/null
+++ b/Data/FoldApp/Generic.hs
@@ -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)
diff --git a/Data/FoldApp/Identity.hs b/Data/FoldApp/Identity.hs
new file mode 100644
--- /dev/null
+++ b/Data/FoldApp/Identity.hs
@@ -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 @(~)
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -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.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/data-foldapp.cabal b/data-foldapp.cabal
new file mode 100644
--- /dev/null
+++ b/data-foldapp.cabal
@@ -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
