packages feed

concatenative 0.0.0 → 1.0.0

raw patch · 2 files changed

+215/−26 lines, 2 filesdep +template-haskellPVP ok

version bump matches the API change (PVP)

Dependencies added: template-haskell

API changes (from Hackage documentation)

+ Control.Concatenative: (&.) :: (a -> b) -> (a -> e) -> Concatenative a b (e -> c) c
+ Control.Concatenative: (*.) :: (t -> b) -> (a -> b1) -> Concatenative a b (b1 -> c) (t -> c)
+ Control.Concatenative: (.&.) :: Concatenative a b c d -> (a -> e) -> Concatenative a b (e -> c) d
+ Control.Concatenative: (.*.) :: Concatenative a b c d -> (e -> f) -> Concatenative e b (f -> c) (a -> d)
+ Control.Concatenative: Concatenative :: ((b -> c) -> (a -> d)) -> Concatenative a b c d
+ Control.Concatenative: apM :: Int -> Q Exp
+ Control.Concatenative: apM_ :: (Monad m) => Int -> m a -> m ()
+ Control.Concatenative: apN :: Int -> Q Exp
+ Control.Concatenative: biApM :: (Monad m) => (t -> m t1) -> (t1 -> t1 -> m t2) -> t -> t -> m t2
+ Control.Concatenative: biApM_ :: (Monad m) => (t -> m t1) -> t -> t -> m ()
+ Control.Concatenative: biM :: (Monad m) => (a -> m b) -> (a -> m c) -> (b -> c -> m d) -> a -> m d
+ Control.Concatenative: biM_ :: (Monad m) => (a -> m b) -> (a -> m c) -> a -> m ()
+ Control.Concatenative: biSpM :: (Monad m) => (a -> m c) -> (b -> m d) -> (c -> d -> m e) -> a -> b -> m e
+ Control.Concatenative: cat :: (a -> b) -> Concatenative a b c c
+ Control.Concatenative: catM :: (Monad m) => (a -> m b) -> Concatenative a b (m c) (m c)
+ Control.Concatenative: cl :: (Monad m) => (a -> m b) -> (a -> m e) -> Concatenative a b (e -> m d) (m d)
+ Control.Concatenative: clM :: (Monad m) => Concatenative a b c (m d) -> (a -> m e) -> Concatenative a b (e -> c) (m d)
+ Control.Concatenative: newtype Concatenative a b c d
+ Control.Concatenative: sp :: (Monad m) => (a -> m b) -> (e -> m f) -> Concatenative e b (f -> m d) (a -> m d)
+ Control.Concatenative: spM :: (Monad m) => Concatenative a b c (m d) -> (e -> m f) -> Concatenative e b (f -> c) (a -> m d)
+ Control.Concatenative: triApM :: (Monad m) => (a -> m b) -> (b -> b -> b -> m c) -> a -> a -> a -> m c
+ Control.Concatenative: triApM_ :: (Monad m) => (a -> m b) -> a -> a -> a -> m ()
+ Control.Concatenative: triM :: (Monad m) => (a -> m b) -> (a -> m c) -> (a -> m d) -> (b -> c -> d -> m e) -> a -> m e
+ Control.Concatenative: triM_ :: (Monad m) => (a -> m b) -> (a -> m c) -> (a -> m d) -> a -> m ()
+ Control.Concatenative: triSpM :: (Monad m) => (a -> m d) -> (b -> m e) -> (c -> m f) -> (d -> e -> f -> m g) -> a -> b -> c -> m g
+ Control.Concatenative: with :: Concatenative a b c d -> (b -> c) -> (a -> d)

Files

Control/Concatenative.hs view
@@ -1,56 +1,172 @@-{-| Control.Concatenative brings postfix notation in the style of factor-    (see http://factorcode.org) to haskell.  Interfaces using both-    combinators and arrows are available.  +{-# LANGUAGE TemplateHaskell #-}+{-| Control.Concatenative brings concatenative combinators in the style of factor+    (see <http://docs.factorcode.org/content/article-dataflow-combinators.html>)+    to haskell in a variety of interfaces, allowing a terse, pointfree style.  -} module Control.Concatenative (     -- * Postfix combinators+    +    -- | These concatenative combinators essentially apply multiple functions to+    --   one or more values before combining all the results using another+    --   function.+    --   Without concatenative combinators:+    --+    -- > \x-> (x+1) + (subtract 1 x)+    --+    --   With concatenative combinators:+    --+    -- > bi (+1) (subtract 1) (+)+         bi, tri, biSp, triSp, biAp, triAp, ifte,-    -- * Postfix arrows +    biM, triM, biSpM, triSpM, biApM, triApM,+    biM_, triM_, biApM_, triApM_,+    +    -- * Postfix arrows+    +    -- | The arrow functions '&&&' and '***' are equivalent to 'bi' and 'biSp'.+    -- Combining here must be done seperately, through the '>>@' function.+         (>>@), dup, swap, both,-    (>>>), (&&&), (***), first, second+    (>>>), (&&&), (***), first, second,+    +    -- * Generalized Datatypes+    +    -- | The Concatenative datatype can be used to cleave, spread, or+    --   apply any number of functions and values. +    --   Using the 'bi' combinator:+    --+    -- > bi (+1) (subtract 1) (+)+    --+    --   is equivalent to using the '&.' function:+    --+    -- > with ((+1) &. (subtract 1)) (+)+    --+    --   and may be generalized to any number of functions:+    --+    -- > with ((subtract 10) &. (+1) .&. (*50)) enumFromThenTo+    --+    --   '*.' similarly generalizes 'biSp', and 'cl' and 'sp' generalize+    --   their monadic variants. Generic application presents a problem for the+    --   type system, however, and the library resorts to template haskell:+    --+    -- > biAp (+1)+    --+    --   translates to+    --+    -- > $(apN 2) (+1)+    +    Concatenative(..),+    cat, (&.), (.&.), (*.), (.*.),+    catM, clM, cl, spM, sp,+    apN, apM, apM_     ) where import Control.Arrow+import Control.Monad+import Language.Haskell.TH  -- Function Interface --- |Apply both arguments to a and combine the results+-- | Apply both arguments to a and combine the results bi :: (a -> b) -> (a -> c) -> (b -> c -> d) -> a -> d-bi f g c = \x-> c (f x) (g x)+bi f g c x = c (f x) (g x) --- |Apply each of three arguments to a and combine the results+-- | Apply each of three arguments to a and combine the results tri :: (a -> b) -> (a -> c) -> (a -> d) -> (b -> c -> d -> e) -> a -> e-tri f g h c = \x-> c (f x) (g x) (h x)+tri f g h c x = c (f x) (g x) (h x) --- |Apply the first argument to a, the second to b, and combine the results+-- | Apply the first argument to a, the second to b, and combine the results biSp :: (a -> c) -> (b -> d) -> (c -> d -> e) -> a -> b -> e-biSp f g c = \x y-> c (f x) (g y)+biSp f g c x y = c (f x) (g y) --- |Apply the first argument to a, the second to b, and the third to c, combining the results+-- | Apply the first argument to a, the second to b, and the third to c, combining the results triSp :: (a -> d) -> (b -> e) -> (c -> f) -> (d -> e -> f -> g) -> a -> b -> c -> g-triSp f g h c = \x y z-> c (f x) (g y) (h z)+triSp f g h c x y z = c (f x) (g y) (h z) --- |Apply a function to two values and combine the results+-- | Apply a function to two values and combine the results biAp :: (t -> t1) -> (t1 -> t1 -> t2) -> t -> t -> t2-biAp f c = \x y-> c (f x) (f y)+biAp f c x y = c (f x) (f y) --- |Apply a function to three values and combine the results+-- | Apply a function to three values and combine the results triAp :: (a -> b) -> (b -> b -> b -> c) -> a -> a -> a -> c-triAp f c = \x y z-> c (f x) (f y) (f z)+triAp f c x y z = c (f x) (f y) (f z)  ifte :: (a -> Bool) -- ^ A predicate      -> (a -> b)    -- ^ Applied if the predicate yields True      -> (a -> b)    -- ^ Applied if the predicate yields False      -> a -> b-ifte test ca cb = \x ->+ifte test ca cb x =     if test x then ca x else cb x +-- Monad Utilities++-- | Like 'bi', but functions can return monadic values+biM :: Monad m => (a -> m b) -> (a -> m c) -> (b -> c -> m d) -> a -> m d+biM f g c a = do+    x <- f a+    y <- g a+    c x y++-- | Like 'biM', but throws away the end result+biM_ :: Monad m => (a -> m b) -> (a -> m c) -> a -> m ()+biM_ f g a = f a >> g a >> return ()++-- | Like 'tri', but functions can return monadic values+triM :: Monad m => (a -> m b) -> (a -> m c) -> (a -> m d) -> (b -> c -> d -> m e) -> a -> m e+triM f g l c a = do+    x <- f a+    y <- g a+    z <- l a+    c x y z++-- | Like 'triM', but throws away the end result+triM_ :: Monad m => (a -> m b) -> (a -> m c) -> (a -> m d) -> a -> m ()+triM_ f g l a = f a >> g a >> l a >> return ()++-- | Like 'biSp', but functions can return monadic values+biSpM :: Monad m => (a -> m c) -> (b -> m d) -> (c -> d -> m e) -> a -> b -> m e+biSpM f g c x y = do+    a <- f x+    b <- g y+    c a b++-- | Like 'triSp', but functions can return monadic values+triSpM :: Monad m => (a -> m d) -> (b -> m e) -> (c -> m f) -> (d -> e -> f -> m g) -> a -> b -> c -> m g+triSpM f g h c x y z = do+    a <- f x+    b <- g y+    n <- h z+    c a b n++-- | Like 'biAp', but functions can return monadic values+biApM :: Monad m => (t -> m t1) -> (t1 -> t1 -> m t2) -> t -> t -> m t2+biApM f c x y = do+    a <- f x+    b <- f y+    c a b++-- | Like 'biApM', but throws away the end result+biApM_ :: Monad m => (t -> m t1) -> t -> t -> m ()+biApM_ f x y = f x >> f y >> return ()++-- | Like 'triAp', but functions can return monadic values+triApM :: Monad m => (a -> m b) -> (b -> b -> b -> m c) -> a -> a -> a -> m c+triApM f c x y z = do+    a <- f x+    b <- f y+    n <- f z+    c a b n++-- | Like 'triApM', but throws away the end result+triApM_ :: Monad m => (a -> m b) -> a -> a -> a-> m ()+triApM_ f x y z = f x >> f y >> f z >> return ()+ -- Arrow Interface --- |Combine with a binary function+-- | Combine with a binary function (>>@) :: Arrow a => a b (x,y) -> (x -> y -> z) -> a b z a >>@ f = a >>> arr (\(x,y) -> f x y) --- |Arrow version of biAp+-- | Arrow version of 'biAp' both :: Arrow a => a b c -> a (b,b) (c,c) both a = first a >>> second a @@ -59,3 +175,78 @@  swap :: Arrow a => a (x,y) (y,x) swap = arr (\(x,y) -> (y,x))++-- Datatypes++-- | Concatenative continuation+newtype Concatenative a b c d = Concatenative { with :: (b -> c) -> (a -> d) }++-- | Lifts a function into 'Concatenative'+cat :: (a -> b) -> Concatenative a b c c+cat f = Concatenative (.f)++-- | Construct a 'Concatenative' for cleaving+(.&.) :: Concatenative a b c d -> (a -> e) -> Concatenative a b (e -> c) d+(Concatenative l) .&. f = Concatenative $ \c a-> l (flip c (f a)) a++-- | Lift a function and add it to a 'Concatenative' for cleaving+(&.) :: (a -> b) -> (a -> e) -> Concatenative a b (e -> c) c+f &. g = (cat f) .&. g++-- | Construct a 'Concatenative' for spreading+(.*.) :: Concatenative a b c d -> (e -> f) -> Concatenative e b (f -> c) (a -> d)+(Concatenative l) .*. f = Concatenative $ \c e-> l (flip c (f e))++-- | Lift a function and add it to a 'Concatenative' for spreading+(*.) :: (t -> b) -> (a -> b1) -> Concatenative a b (b1 -> c) (t -> c)+f *. g = (cat f) .*. g++-- | Lift a monadic function to a 'Concatenative'+catM :: Monad m => (a -> m b) -> Concatenative a b (m c) (m c)+catM f = Concatenative $ \c a-> f a >>= c++-- | Construct a 'Concatenative' for spreading monadic functions+clM :: Monad m => Concatenative a b c (m d) -> (a -> m e) -> Concatenative a b (e -> c) (m d)+(Concatenative l) `clM ` f = Concatenative $ \c a-> f a >>= (\x-> l (flip c x) a)++-- | Lift a monadic function and add it to a 'Concatenative' for cleaving+cl :: (Monad m) => (a -> m b) -> (a -> m e) -> Concatenative a b (e -> m d) (m d)+f `cl` g = (catM f) `clM` g++-- | Construct a 'Concatenative' for spreading monadic functions+spM :: Monad m => Concatenative a b c (m d) -> (e -> m f) -> Concatenative e b (f -> c) (a -> m d)+(Concatenative l) `spM` f = Concatenative $ \c e a-> f e >>= \x-> l (flip c x) a ++-- | Lift a monadic function and add it to a 'Concatenative' for spreading+sp :: (Monad m) => (a -> m b) -> (e -> m f) -> Concatenative e b (f -> m d) (a -> m d)+f `sp` g = (catM f) `spM` g++-- | Create a 'Concatenative' for applying a function n times+--+-- > biAp (+1)+--+--   translates to+--+-- > $(apN 2) (+1)+apN :: Int -> Q Exp+apN n = [| \f-> $(apN' n) f |] where+    apN' :: Int -> Q Exp+    apN' n | n > 1 = [| \f-> $(apN' (n-1)) f .*. f |]+           | otherwise = [| cat |]++-- | Create a 'Concatenative' for applying a monadic function n times+--+-- > biApM (+1)+--+--   translates to+--+-- > $(apM 2) (+1)+apM :: Int -> Q Exp+apM n = [| \f-> $(apM' n) f |] where+    apM' :: Int -> Q Exp+    apM' n | n > 1 = [| \f-> $(apM' (n-1)) f `spM` f |]+           | otherwise = [| catM |]++-- | Convenience synonym for 'replicateM_'+apM_ :: Monad m => Int -> m a -> m ()+apM_ = replicateM_
concatenative.cabal view
@@ -1,5 +1,5 @@ name:                concatenative-version:             0.0.0+version:             1.0.0 synopsis:            A library for postfix control flow. description:         Concatenative gives haskell factor style                      combinators and arrows for postfix notation.@@ -10,10 +10,8 @@ license-file:        LICENSE author:              Sam Anklesaria maintainer:          amsay@amsay.net-build-depends:       base >= 3 && < 5+build-depends:       base >= 3 && < 5, template-haskell > 2 && < 3 build-type:          Simple Cabal-Version:       >= 1.2--Library-    exposed-modules:  Control.Concatenative-    Build-Depends:    base >= 3 && < 5+exposed-modules:     Control.Concatenative+homepage:            https://patch-tag.com/r/salazar/concatenative/snapshot/current/content/pretty