ReplicateEffects 0.2 → 0.3
raw patch · 2 files changed
+61/−34 lines, 2 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Control.Replicate: instance Arrow Replicate
+ Control.Replicate: instance ArrowPlus Replicate
+ Control.Replicate: instance ArrowZero Replicate
- Control.Replicate: Cons :: (Maybe b) -> (Replicate a (a -> b)) -> Replicate a b
+ Control.Replicate: Cons :: (c -> b) -> Maybe c -> Replicate a (a -> c) -> Replicate a b
- Control.Replicate: sizes :: Num num => Replicate a b -> [num]
+ Control.Replicate: sizes :: Replicate a b -> [Int]
Files
- Control/Replicate.hs +54/−30
- ReplicateEffects.cabal +7/−4
Control/Replicate.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE GADTs, Rank2Types #-} -- | Composable replication schemes of applicative actions. -- -- This module separates common combinators such as @some@ and @many@ (from@@ -89,19 +90,34 @@ import Data.Monoid import Control.Applicative hiding (many, some) import Control.Category+import Control.Arrow + -- | A set of frequencies which with an applicative action is allowed to -- occur. @a@ is the result type of a single atomic action. @b@ is the -- composite result type after executing the action a number of times allowed -- by this set.-data Replicate a b- = Nil- | Cons (Maybe b) (Replicate a (a -> b))+data Replicate a b where+ Nil :: Replicate a b+ Cons :: (c -> b) -> Maybe c -> Replicate a (a -> c) -> Replicate a b +-- Fold the Replicate list given:+-- * an "empty" value+-- * a function to combine the Cons value into the result+-- * a function to convert the value of the recursive call to the expected type+foldReplicate :: (forall c. f c) + -> (forall c. c -> f c -> f c) + -> (forall c. f (a -> c) -> f c) + -> Replicate a b -> f b+foldReplicate e _ _ Nil = e+foldReplicate e f g (Cons fx mx xs) = + maybe id (f . fx) mx . g . foldReplicate e f g . fmap (fx .) $ xs++ -- | Map over the composite result type. instance Functor (Replicate a) where fmap _ Nil = Nil- fmap f (Cons mx xs) = Cons (f <$> mx) (fmap (f .) xs)+ fmap f (Cons fx mx xs) = Cons (f . fx) mx xs -- | Pairwise addition. -- @@ -124,10 +140,10 @@ -- lowerBound (f1 <*> f2) = lowerBound f1 + lowerBound f2 -- upperBound (f1 <*> f2) = upperBound f1 + upperBound f2 Nil <*> _ = Nil- Cons mx xs <*> ys = -- 0 + n = n- maybe empty (<$> ys) mx+ Cons fx mx xs <*> ys = -- 0 + n = n+ maybe empty ((<$> ys) . fx) mx <|> -- (1 + m) + n = 1 + (m + n)- Cons Nothing (flip <$> xs <*> ys)+ Cons id Nothing ((\x y z -> fx (x z) y) <$> xs <*> ys) -- | 'empty' is the empty set {} of allowed occurrences. Not even performing -- an action zero times is allowed in that case.@@ -140,9 +156,9 @@ Nil <|> ys = ys xs <|> Nil = xs- Cons mx xs <|> Cons my ys =+ Cons fx mx xs <|> Cons fy my ys = -- <|> on Maybes discards the right operand if the left is a Just.- Cons (mx <|> my) (xs <|> ys)+ Cons id (fx <$> mx <|> fy <$> my) (fmap fx <$> xs <|> fmap fy <$> ys) -- | Behaves exactly as the 'Alternative' instance. instance Monoid (Replicate a b) where@@ -157,47 +173,55 @@ -- '.' produces the set of occurrences that are the products of all possible -- pairs from the two operands. instance Category Replicate where- id = one- Nil . _ = Nil- Cons mx xs . ys = -- 0 * n = 0- maybe empty zero mx- <|> -- (m + 1) * n = m * n + n- ys <**> (xs . ys)+ id = one+ (.) = (*?) +-- | As 'Replicate' is both 'Applicative' and 'Category', it is also an 'Arrow'.+instance Arrow Replicate where+ arr f = f <$> id+ f &&& g = (,) <$> f <*> g+ f *** g = f . arr fst &&& g . arr snd+ first f = f *** id+ second f = id *** f +-- | Behaves exactly as the 'Alternative' instance.+instance ArrowZero Replicate where+ zeroArrow = empty+-- | Behaves exactly as the 'Alternative' instance.+instance ArrowPlus Replicate where+ (<+>) = (<|>)++ -- | Run an action a certain number of times, using '<|>' to branch (at the -- deepest point possible) if multiple frequencies are allowed. Use greedy -- choices: always make the longer alternative the left operand of @\<|\>@. (*!) :: Alternative f => Replicate a b -> f a -> f b-Nil *! _ = empty-Cons mx xs *! p = p <**> (xs *! p) <|> maybe empty pure mx+r *! p = foldReplicate empty (\x xs -> xs <|> pure x) (p <**>) r -- | Run an action a certain number of times, using '<|>' to branch (at the -- deepest point possible) if multiple frequencies are allowed. Use lazy -- choices: always make the 'pure' alternative the left operand of @\<|\>@. (*?) :: Alternative f => Replicate a b -> f a -> f b-Nil *? _ = empty-Cons mx xs *? p = maybe empty pure mx <|> p <**> (xs *? p)+r *? p = foldReplicate empty (\x xs -> pure x <|> xs) (p <**>) r + -- | Enumerate all the numbers of allowed occurrences encoded by the -- replication scheme.-sizes :: Num num => Replicate a b -> [num]-sizes = sizes' 0- where- -- Type signature is mandatory here.- sizes' :: Num num => num -> Replicate a b -> [num]- sizes' _ Nil = []- sizes' n (Cons mx xs) = maybe [] (const [n]) mx ++ sizes' (n + 1) xs-+sizes :: Replicate a b -> [Int]+sizes = ($ 0) . getConst . sizesFold where+ sizesFold = foldReplicate + ( Const (\_ -> []))+ (\_ (Const g) -> Const (\n -> n : g n))+ (\ (Const g) -> Const (\n -> g (n + 1))) -- | Perform an action exactly zero times. zero :: b -> Replicate a b-zero x = Cons (Just x) Nil+zero x = Cons id (Just x) Nil -- | Perform an action exactly one time. one :: Replicate a a-one = Cons Nothing (zero id)+one = Cons id Nothing (zero id) -- | Perform an action exactly two times. two :: Replicate a (a, a)@@ -239,4 +263,4 @@ -- | Repeat an action forever. forever :: Replicate a b-forever = Cons Nothing (const <$> forever)+forever = Cons id Nothing (const <$> forever)
ReplicateEffects.cabal view
@@ -1,5 +1,5 @@ Name: ReplicateEffects-Version: 0.2+Version: 0.3 Synopsis: Composable replication schemes of applicative functors -- Description: Category: Control@@ -13,10 +13,13 @@ Bug-reports: https://github.com/MedeaMelana/ReplicateEffects/issues -- Copyright: - Build-type: Simple-Cabal-version: >= 1.2+Cabal-version: >= 1.6 Library Exposed-modules: Control.Replicate- Build-depends: base >= 4.0 && < 4.4+ Build-depends: base >= 4.0 && < 5++Source-Repository head+ Type: Git+ Location: https://github.com/MedeaMelana/ReplicateEffects