gambler 0.0.1.0 → 0.1.0.0
raw patch · 47 files changed
+1799/−604 lines, 47 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Fold.Effectful.Nonempty: first :: Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Nonempty: last :: Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Nonempty: magma :: (a -> a -> a) -> Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Nonempty: maximum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Nonempty: maximumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Nonempty: minimum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Nonempty: minimumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Nonempty: semigroup :: Semigroup a => Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Pure: all :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
- Fold.Effectful.Pure: and :: Monad m => EffectfulFold m Bool Bool
- Fold.Effectful.Pure: any :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
- Fold.Effectful.Pure: element :: Eq a => Monad m => a -> EffectfulFold m a Bool
- Fold.Effectful.Pure: elementIndex :: Eq a => Monad m => a -> EffectfulFold m a (Maybe Natural)
- Fold.Effectful.Pure: find :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe a)
- Fold.Effectful.Pure: findIndex :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe Natural)
- Fold.Effectful.Pure: index :: Monad m => Natural -> EffectfulFold m a (Maybe a)
- Fold.Effectful.Pure: length :: Monad m => EffectfulFold m a Natural
- Fold.Effectful.Pure: list :: Monad m => EffectfulFold m a [a]
- Fold.Effectful.Pure: lookup :: Eq a => Monad m => a -> EffectfulFold m (a, b) (Maybe b)
- Fold.Effectful.Pure: mean :: Fractional a => Monad m => EffectfulFold m a a
- Fold.Effectful.Pure: monoid :: Monoid a => Monad m => EffectfulFold m a a
- Fold.Effectful.Pure: notElement :: Eq a => Monad m => a -> EffectfulFold m a Bool
- Fold.Effectful.Pure: null :: Monad m => EffectfulFold m a Bool
- Fold.Effectful.Pure: or :: Monad m => EffectfulFold m Bool Bool
- Fold.Effectful.Pure: product :: Num a => Monad m => EffectfulFold m a a
- Fold.Effectful.Pure: reverseList :: Monad m => EffectfulFold m a [a]
- Fold.Effectful.Pure: standardDeviation :: Floating a => Monad m => EffectfulFold m a a
- Fold.Effectful.Pure: sum :: Num a => Monad m => EffectfulFold m a a
- Fold.Effectful.Pure: variance :: Fractional a => Monad m => EffectfulFold m a a
- Fold.Nonempty: null :: NonemptyFold a Bool
- Fold.Nonempty.Pure: all :: (a -> Bool) -> NonemptyFold a Bool
- Fold.Nonempty.Pure: and :: NonemptyFold Bool Bool
- Fold.Nonempty.Pure: any :: (a -> Bool) -> NonemptyFold a Bool
- Fold.Nonempty.Pure: element :: Eq a => a -> NonemptyFold a Bool
- Fold.Nonempty.Pure: elementIndex :: Eq a => a -> NonemptyFold a (Maybe Natural)
- Fold.Nonempty.Pure: find :: (a -> Bool) -> NonemptyFold a (Maybe a)
- Fold.Nonempty.Pure: findIndex :: (a -> Bool) -> NonemptyFold a (Maybe Natural)
- Fold.Nonempty.Pure: index :: Natural -> NonemptyFold a (Maybe a)
- Fold.Nonempty.Pure: length :: NonemptyFold a Natural
- Fold.Nonempty.Pure: list :: NonemptyFold a [a]
- Fold.Nonempty.Pure: lookup :: Eq a => a -> NonemptyFold (a, b) (Maybe b)
- Fold.Nonempty.Pure: mean :: Fractional a => NonemptyFold a a
- Fold.Nonempty.Pure: monoid :: Monoid a => NonemptyFold a a
- Fold.Nonempty.Pure: notElement :: Eq a => a -> NonemptyFold a Bool
- Fold.Nonempty.Pure: null :: NonemptyFold a Bool
- Fold.Nonempty.Pure: or :: NonemptyFold Bool Bool
- Fold.Nonempty.Pure: product :: Num a => NonemptyFold a a
- Fold.Nonempty.Pure: reverseList :: NonemptyFold a [a]
- Fold.Nonempty.Pure: standardDeviation :: Floating a => NonemptyFold a a
- Fold.Nonempty.Pure: sum :: Num a => NonemptyFold a a
- Fold.Nonempty.Pure: variance :: Fractional a => NonemptyFold a a
- Fold.Pure.Nonempty: first :: Fold a (Maybe a)
- Fold.Pure.Nonempty: last :: Fold a (Maybe a)
- Fold.Pure.Nonempty: magma :: (a -> a -> a) -> Fold a (Maybe a)
- Fold.Pure.Nonempty: maximum :: Ord a => Fold a (Maybe a)
- Fold.Pure.Nonempty: maximumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
- Fold.Pure.Nonempty: minimum :: Ord a => Fold a (Maybe a)
- Fold.Pure.Nonempty: minimumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
- Fold.Pure.Nonempty: semigroup :: Semigroup a => Fold a (Maybe a)
+ Fold: Alive :: Will -> b -> Vitality a b
+ Fold: Ambivalent :: Will
+ Fold: Dead :: a -> Vitality a b
+ Fold: ShortcutFold :: Vitality x y -> (y -> a -> Vitality x y) -> (x -> b) -> (y -> b) -> ShortcutFold a b
+ Fold: ShortcutNonemptyFold :: (a -> Vitality x y) -> (y -> a -> Vitality x y) -> (x -> b) -> (y -> b) -> ShortcutNonemptyFold a b
+ Fold: Tenacious :: Will
+ Fold: data ShortcutFold a b
+ Fold: data ShortcutNonemptyFold a b
+ Fold: data Vitality a b
+ Fold: data Will
+ Fold.Effectful: shortcutFold :: Monad m => ShortcutFold a b -> EffectfulFold m a b
+ Fold.Effectful: shortcutNonemptyFold :: Monad m => ShortcutNonemptyFold a b -> EffectfulFold m a (Maybe b)
+ Fold.Effectful.Conversion: shortcutFold :: Monad m => ShortcutFold a b -> EffectfulFold m a b
+ Fold.Effectful.Conversion: shortcutNonemptyFold :: Monad m => ShortcutNonemptyFold a b -> EffectfulFold m a (Maybe b)
+ Fold.Effectful.Examples: all :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
+ Fold.Effectful.Examples: and :: Monad m => EffectfulFold m Bool Bool
+ Fold.Effectful.Examples: any :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
+ Fold.Effectful.Examples: element :: Eq a => Monad m => a -> EffectfulFold m a Bool
+ Fold.Effectful.Examples: elementIndex :: Eq a => Monad m => a -> EffectfulFold m a (Maybe Natural)
+ Fold.Effectful.Examples: find :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples: findIndex :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe Natural)
+ Fold.Effectful.Examples: first :: Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples: index :: Monad m => Natural -> EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples: last :: Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples: length :: Monad m => EffectfulFold m a Natural
+ Fold.Effectful.Examples: list :: Monad m => EffectfulFold m a [a]
+ Fold.Effectful.Examples: lookup :: Eq a => Monad m => a -> EffectfulFold m (a, b) (Maybe b)
+ Fold.Effectful.Examples: magma :: (a -> a -> a) -> Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples: maximum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples: maximumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples: mean :: Fractional a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples: minimum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples: minimumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples: monoid :: Monoid a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples: notElement :: Eq a => Monad m => a -> EffectfulFold m a Bool
+ Fold.Effectful.Examples: null :: Monad m => EffectfulFold m a Bool
+ Fold.Effectful.Examples: or :: Monad m => EffectfulFold m Bool Bool
+ Fold.Effectful.Examples: product :: Num a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples: reverseList :: Monad m => EffectfulFold m a [a]
+ Fold.Effectful.Examples: semigroup :: Semigroup a => Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples: standardDeviation :: Floating a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples: sum :: Num a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples: variance :: Fractional a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples.Boring: all :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
+ Fold.Effectful.Examples.Boring: and :: Monad m => EffectfulFold m Bool Bool
+ Fold.Effectful.Examples.Boring: any :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
+ Fold.Effectful.Examples.Boring: element :: Eq a => Monad m => a -> EffectfulFold m a Bool
+ Fold.Effectful.Examples.Boring: elementIndex :: Eq a => Monad m => a -> EffectfulFold m a (Maybe Natural)
+ Fold.Effectful.Examples.Boring: find :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples.Boring: findIndex :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe Natural)
+ Fold.Effectful.Examples.Boring: first :: Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples.Boring: index :: Monad m => Natural -> EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples.Boring: last :: Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples.Boring: length :: Monad m => EffectfulFold m a Natural
+ Fold.Effectful.Examples.Boring: list :: Monad m => EffectfulFold m a [a]
+ Fold.Effectful.Examples.Boring: lookup :: Eq a => Monad m => a -> EffectfulFold m (a, b) (Maybe b)
+ Fold.Effectful.Examples.Boring: magma :: (a -> a -> a) -> Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples.Boring: maximum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples.Boring: maximumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples.Boring: mean :: Fractional a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples.Boring: minimum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples.Boring: minimumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples.Boring: monoid :: Monoid a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples.Boring: notElement :: Eq a => Monad m => a -> EffectfulFold m a Bool
+ Fold.Effectful.Examples.Boring: null :: Monad m => EffectfulFold m a Bool
+ Fold.Effectful.Examples.Boring: or :: Monad m => EffectfulFold m Bool Bool
+ Fold.Effectful.Examples.Boring: product :: Num a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples.Boring: reverseList :: Monad m => EffectfulFold m a [a]
+ Fold.Effectful.Examples.Boring: semigroup :: Semigroup a => Monad m => EffectfulFold m a (Maybe a)
+ Fold.Effectful.Examples.Boring: standardDeviation :: Floating a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples.Boring: sum :: Num a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples.Boring: variance :: Fractional a => Monad m => EffectfulFold m a a
+ Fold.Effectful.Examples.Interesting: effect :: Monad m => (a -> m b) -> EffectfulFold m a ()
+ Fold.Effectful.Examples.Interesting: effectMonoid :: (Monoid w, Monad m) => (a -> m w) -> EffectfulFold m a w
+ Fold.Nonempty: shortcutFold :: ShortcutFold a b -> NonemptyFold a b
+ Fold.Nonempty: shortcutNonemptyFold :: ShortcutNonemptyFold a b -> NonemptyFold a b
+ Fold.Nonempty.Conversion: shortcutFold :: ShortcutFold a b -> NonemptyFold a b
+ Fold.Nonempty.Conversion: shortcutNonemptyFold :: ShortcutNonemptyFold a b -> NonemptyFold a b
+ Fold.Nonempty.Examples: all :: (a -> Bool) -> NonemptyFold a Bool
+ Fold.Nonempty.Examples: and :: NonemptyFold Bool Bool
+ Fold.Nonempty.Examples: any :: (a -> Bool) -> NonemptyFold a Bool
+ Fold.Nonempty.Examples: element :: Eq a => a -> NonemptyFold a Bool
+ Fold.Nonempty.Examples: elementIndex :: Eq a => a -> NonemptyFold a (Maybe Natural)
+ Fold.Nonempty.Examples: find :: (a -> Bool) -> NonemptyFold a (Maybe a)
+ Fold.Nonempty.Examples: findIndex :: (a -> Bool) -> NonemptyFold a (Maybe Natural)
+ Fold.Nonempty.Examples: index :: Natural -> NonemptyFold a (Maybe a)
+ Fold.Nonempty.Examples: length :: NonemptyFold a Natural
+ Fold.Nonempty.Examples: lookup :: Eq a => a -> NonemptyFold (a, b) (Maybe b)
+ Fold.Nonempty.Examples: mean :: Fractional a => NonemptyFold a a
+ Fold.Nonempty.Examples: monoid :: Monoid a => NonemptyFold a a
+ Fold.Nonempty.Examples: notElement :: Eq a => a -> NonemptyFold a Bool
+ Fold.Nonempty.Examples: or :: NonemptyFold Bool Bool
+ Fold.Nonempty.Examples: product :: Num a => NonemptyFold a a
+ Fold.Nonempty.Examples: standardDeviation :: Floating a => NonemptyFold a a
+ Fold.Nonempty.Examples: sum :: Num a => NonemptyFold a a
+ Fold.Nonempty.Examples: variance :: Fractional a => NonemptyFold a a
+ Fold.Nonempty.Examples.Boring: all :: (a -> Bool) -> NonemptyFold a Bool
+ Fold.Nonempty.Examples.Boring: and :: NonemptyFold Bool Bool
+ Fold.Nonempty.Examples.Boring: any :: (a -> Bool) -> NonemptyFold a Bool
+ Fold.Nonempty.Examples.Boring: element :: Eq a => a -> NonemptyFold a Bool
+ Fold.Nonempty.Examples.Boring: elementIndex :: Eq a => a -> NonemptyFold a (Maybe Natural)
+ Fold.Nonempty.Examples.Boring: find :: (a -> Bool) -> NonemptyFold a (Maybe a)
+ Fold.Nonempty.Examples.Boring: findIndex :: (a -> Bool) -> NonemptyFold a (Maybe Natural)
+ Fold.Nonempty.Examples.Boring: first :: NonemptyFold a a
+ Fold.Nonempty.Examples.Boring: index :: Natural -> NonemptyFold a (Maybe a)
+ Fold.Nonempty.Examples.Boring: length :: NonemptyFold a Natural
+ Fold.Nonempty.Examples.Boring: list :: NonemptyFold a [a]
+ Fold.Nonempty.Examples.Boring: lookup :: Eq a => a -> NonemptyFold (a, b) (Maybe b)
+ Fold.Nonempty.Examples.Boring: mean :: Fractional a => NonemptyFold a a
+ Fold.Nonempty.Examples.Boring: monoid :: Monoid a => NonemptyFold a a
+ Fold.Nonempty.Examples.Boring: notElement :: Eq a => a -> NonemptyFold a Bool
+ Fold.Nonempty.Examples.Boring: or :: NonemptyFold Bool Bool
+ Fold.Nonempty.Examples.Boring: product :: Num a => NonemptyFold a a
+ Fold.Nonempty.Examples.Boring: reverseList :: NonemptyFold a [a]
+ Fold.Nonempty.Examples.Boring: standardDeviation :: Floating a => NonemptyFold a a
+ Fold.Nonempty.Examples.Boring: sum :: Num a => NonemptyFold a a
+ Fold.Nonempty.Examples.Boring: variance :: Fractional a => NonemptyFold a a
+ Fold.Nonempty.Examples.Interesting: last :: NonemptyFold a a
+ Fold.Nonempty.Examples.Interesting: list :: NonemptyFold a (NonEmpty a)
+ Fold.Nonempty.Examples.Interesting: magma :: (a -> a -> a) -> NonemptyFold a a
+ Fold.Nonempty.Examples.Interesting: maximum :: Ord a => NonemptyFold a a
+ Fold.Nonempty.Examples.Interesting: maximumBy :: (a -> a -> Ordering) -> NonemptyFold a a
+ Fold.Nonempty.Examples.Interesting: minimum :: Ord a => NonemptyFold a a
+ Fold.Nonempty.Examples.Interesting: minimumBy :: (a -> a -> Ordering) -> NonemptyFold a a
+ Fold.Nonempty.Examples.Interesting: reverseList :: NonemptyFold a (NonEmpty a)
+ Fold.Nonempty.Examples.Interesting: semigroup :: Semigroup a => NonemptyFold a a
+ Fold.Pure: shortcutFold :: ShortcutFold a b -> Fold a b
+ Fold.Pure: shortcutNonemptyFold :: ShortcutNonemptyFold a b -> Fold a (Maybe b)
+ Fold.Pure.Conversion: shortcutFold :: ShortcutFold a b -> Fold a b
+ Fold.Pure.Conversion: shortcutNonemptyFold :: ShortcutNonemptyFold a b -> Fold a (Maybe b)
+ Fold.Pure.Examples: first :: Fold a (Maybe a)
+ Fold.Pure.Examples: last :: Fold a (Maybe a)
+ Fold.Pure.Examples: magma :: (a -> a -> a) -> Fold a (Maybe a)
+ Fold.Pure.Examples: maximum :: Ord a => Fold a (Maybe a)
+ Fold.Pure.Examples: maximumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
+ Fold.Pure.Examples: minimum :: Ord a => Fold a (Maybe a)
+ Fold.Pure.Examples: minimumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
+ Fold.Pure.Examples: semigroup :: Semigroup a => Fold a (Maybe a)
+ Fold.Pure.Examples.Boring: all :: (a -> Bool) -> Fold a Bool
+ Fold.Pure.Examples.Boring: and :: Fold Bool Bool
+ Fold.Pure.Examples.Boring: any :: (a -> Bool) -> Fold a Bool
+ Fold.Pure.Examples.Boring: element :: Eq a => a -> Fold a Bool
+ Fold.Pure.Examples.Boring: elementIndex :: Eq a => a -> Fold a (Maybe Natural)
+ Fold.Pure.Examples.Boring: find :: (a -> Bool) -> Fold a (Maybe a)
+ Fold.Pure.Examples.Boring: findIndex :: (a -> Bool) -> Fold a (Maybe Natural)
+ Fold.Pure.Examples.Boring: first :: Fold a (Maybe a)
+ Fold.Pure.Examples.Boring: index :: Natural -> Fold a (Maybe a)
+ Fold.Pure.Examples.Boring: last :: Fold a (Maybe a)
+ Fold.Pure.Examples.Boring: lookup :: Eq a => a -> Fold (a, b) (Maybe b)
+ Fold.Pure.Examples.Boring: magma :: (a -> a -> a) -> Fold a (Maybe a)
+ Fold.Pure.Examples.Boring: maximum :: Ord a => Fold a (Maybe a)
+ Fold.Pure.Examples.Boring: maximumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
+ Fold.Pure.Examples.Boring: minimum :: Ord a => Fold a (Maybe a)
+ Fold.Pure.Examples.Boring: minimumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
+ Fold.Pure.Examples.Boring: notElement :: Eq a => a -> Fold a Bool
+ Fold.Pure.Examples.Boring: null :: Fold a Bool
+ Fold.Pure.Examples.Boring: or :: Fold Bool Bool
+ Fold.Pure.Examples.Boring: semigroup :: Semigroup a => Fold a (Maybe a)
+ Fold.Pure.Examples.Interesting: length :: Fold a Natural
+ Fold.Pure.Examples.Interesting: list :: Fold a [a]
+ Fold.Pure.Examples.Interesting: mean :: Fractional a => Fold a a
+ Fold.Pure.Examples.Interesting: monoid :: Monoid a => Fold a a
+ Fold.Pure.Examples.Interesting: product :: Num a => Fold a a
+ Fold.Pure.Examples.Interesting: reverseList :: Fold a [a]
+ Fold.Pure.Examples.Interesting: standardDeviation :: Floating a => Fold a a
+ Fold.Pure.Examples.Interesting: sum :: Num a => Fold a a
+ Fold.Pure.Examples.Interesting: variance :: Fractional a => Fold a a
+ Fold.Shortcut: ShortcutFold :: Vitality x y -> (y -> a -> Vitality x y) -> (x -> b) -> (y -> b) -> ShortcutFold a b
+ Fold.Shortcut: [extractDead] :: ShortcutFold a b -> x -> b
+ Fold.Shortcut: [extractLive] :: ShortcutFold a b -> y -> b
+ Fold.Shortcut: [initial] :: ShortcutFold a b -> Vitality x y
+ Fold.Shortcut: [step] :: ShortcutFold a b -> y -> a -> Vitality x y
+ Fold.Shortcut: all :: (a -> Bool) -> ShortcutFold a Bool
+ Fold.Shortcut: and :: ShortcutFold Bool Bool
+ Fold.Shortcut: any :: (a -> Bool) -> ShortcutFold a Bool
+ Fold.Shortcut: data ShortcutFold a b
+ Fold.Shortcut: demotivate :: ShortcutFold a b -> ShortcutFold a b
+ Fold.Shortcut: effectfulFold :: EffectfulFold Identity a b -> ShortcutFold a b
+ Fold.Shortcut: element :: Eq a => a -> ShortcutFold a Bool
+ Fold.Shortcut: elementIndex :: Eq a => a -> ShortcutFold a (Maybe Natural)
+ Fold.Shortcut: find :: (a -> Bool) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut: findIndex :: (a -> Bool) -> ShortcutFold a (Maybe Natural)
+ Fold.Shortcut: first :: ShortcutFold a (Maybe a)
+ Fold.Shortcut: fold :: Fold a b -> ShortcutFold a b
+ Fold.Shortcut: index :: Natural -> ShortcutFold a (Maybe a)
+ Fold.Shortcut: last :: ShortcutFold a (Maybe a)
+ Fold.Shortcut: length :: ShortcutFold a Natural
+ Fold.Shortcut: list :: ShortcutFold a [a]
+ Fold.Shortcut: lookup :: Eq a => a -> ShortcutFold (a, b) (Maybe b)
+ Fold.Shortcut: magma :: (a -> a -> a) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut: maximum :: Ord a => ShortcutFold a (Maybe a)
+ Fold.Shortcut: maximumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut: mean :: Fractional a => ShortcutFold a a
+ Fold.Shortcut: minimum :: Ord a => ShortcutFold a (Maybe a)
+ Fold.Shortcut: minimumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut: monoid :: Monoid a => ShortcutFold a a
+ Fold.Shortcut: nonemptyFold :: NonemptyFold a b -> ShortcutFold a (Maybe b)
+ Fold.Shortcut: notElement :: Eq a => a -> ShortcutFold a Bool
+ Fold.Shortcut: null :: ShortcutFold a Bool
+ Fold.Shortcut: or :: ShortcutFold Bool Bool
+ Fold.Shortcut: product :: Num a => ShortcutFold a a
+ Fold.Shortcut: reverseList :: ShortcutFold a [a]
+ Fold.Shortcut: run :: ShortcutFold a b -> [a] -> b
+ Fold.Shortcut: semigroup :: Semigroup a => ShortcutFold a (Maybe a)
+ Fold.Shortcut: shortcutNonemptyFold :: ShortcutNonemptyFold a b -> ShortcutFold a (Maybe b)
+ Fold.Shortcut: standardDeviation :: Floating a => ShortcutFold a a
+ Fold.Shortcut: sum :: Num a => ShortcutFold a a
+ Fold.Shortcut: variance :: Fractional a => ShortcutFold a a
+ Fold.Shortcut.Conversion: effectfulFold :: EffectfulFold Identity a b -> ShortcutFold a b
+ Fold.Shortcut.Conversion: fold :: Fold a b -> ShortcutFold a b
+ Fold.Shortcut.Conversion: nonemptyFold :: NonemptyFold a b -> ShortcutFold a (Maybe b)
+ Fold.Shortcut.Conversion: shortcutNonemptyFold :: ShortcutNonemptyFold a b -> ShortcutFold a (Maybe b)
+ Fold.Shortcut.Examples: all :: (a -> Bool) -> ShortcutFold a Bool
+ Fold.Shortcut.Examples: and :: ShortcutFold Bool Bool
+ Fold.Shortcut.Examples: any :: (a -> Bool) -> ShortcutFold a Bool
+ Fold.Shortcut.Examples: element :: Eq a => a -> ShortcutFold a Bool
+ Fold.Shortcut.Examples: elementIndex :: Eq a => a -> ShortcutFold a (Maybe Natural)
+ Fold.Shortcut.Examples: find :: (a -> Bool) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples: findIndex :: (a -> Bool) -> ShortcutFold a (Maybe Natural)
+ Fold.Shortcut.Examples: first :: ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples: index :: Natural -> ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples: last :: ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples: length :: ShortcutFold a Natural
+ Fold.Shortcut.Examples: list :: ShortcutFold a [a]
+ Fold.Shortcut.Examples: lookup :: Eq a => a -> ShortcutFold (a, b) (Maybe b)
+ Fold.Shortcut.Examples: magma :: (a -> a -> a) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples: maximum :: Ord a => ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples: maximumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples: mean :: Fractional a => ShortcutFold a a
+ Fold.Shortcut.Examples: minimum :: Ord a => ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples: minimumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples: monoid :: Monoid a => ShortcutFold a a
+ Fold.Shortcut.Examples: notElement :: Eq a => a -> ShortcutFold a Bool
+ Fold.Shortcut.Examples: null :: ShortcutFold a Bool
+ Fold.Shortcut.Examples: or :: ShortcutFold Bool Bool
+ Fold.Shortcut.Examples: product :: Num a => ShortcutFold a a
+ Fold.Shortcut.Examples: reverseList :: ShortcutFold a [a]
+ Fold.Shortcut.Examples: semigroup :: Semigroup a => ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples: standardDeviation :: Floating a => ShortcutFold a a
+ Fold.Shortcut.Examples: sum :: Num a => ShortcutFold a a
+ Fold.Shortcut.Examples: variance :: Fractional a => ShortcutFold a a
+ Fold.Shortcut.Examples.Boring: first :: ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples.Boring: last :: ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples.Boring: length :: ShortcutFold a Natural
+ Fold.Shortcut.Examples.Boring: list :: ShortcutFold a [a]
+ Fold.Shortcut.Examples.Boring: magma :: (a -> a -> a) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples.Boring: maximum :: Ord a => ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples.Boring: maximumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples.Boring: mean :: Fractional a => ShortcutFold a a
+ Fold.Shortcut.Examples.Boring: minimum :: Ord a => ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples.Boring: minimumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples.Boring: monoid :: Monoid a => ShortcutFold a a
+ Fold.Shortcut.Examples.Boring: product :: Num a => ShortcutFold a a
+ Fold.Shortcut.Examples.Boring: reverseList :: ShortcutFold a [a]
+ Fold.Shortcut.Examples.Boring: semigroup :: Semigroup a => ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples.Boring: standardDeviation :: Floating a => ShortcutFold a a
+ Fold.Shortcut.Examples.Boring: sum :: Num a => ShortcutFold a a
+ Fold.Shortcut.Examples.Boring: variance :: Fractional a => ShortcutFold a a
+ Fold.Shortcut.Examples.Interesting: all :: (a -> Bool) -> ShortcutFold a Bool
+ Fold.Shortcut.Examples.Interesting: and :: ShortcutFold Bool Bool
+ Fold.Shortcut.Examples.Interesting: any :: (a -> Bool) -> ShortcutFold a Bool
+ Fold.Shortcut.Examples.Interesting: element :: Eq a => a -> ShortcutFold a Bool
+ Fold.Shortcut.Examples.Interesting: elementIndex :: Eq a => a -> ShortcutFold a (Maybe Natural)
+ Fold.Shortcut.Examples.Interesting: find :: (a -> Bool) -> ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples.Interesting: findIndex :: (a -> Bool) -> ShortcutFold a (Maybe Natural)
+ Fold.Shortcut.Examples.Interesting: index :: Natural -> ShortcutFold a (Maybe a)
+ Fold.Shortcut.Examples.Interesting: lookup :: Eq a => a -> ShortcutFold (a, b) (Maybe b)
+ Fold.Shortcut.Examples.Interesting: notElement :: Eq a => a -> ShortcutFold a Bool
+ Fold.Shortcut.Examples.Interesting: null :: ShortcutFold a Bool
+ Fold.Shortcut.Examples.Interesting: or :: ShortcutFold Bool Bool
+ Fold.Shortcut.Run: run :: ShortcutFold a b -> [a] -> b
+ Fold.Shortcut.Type: Alive :: Will -> b -> Vitality a b
+ Fold.Shortcut.Type: Ambivalent :: Will
+ Fold.Shortcut.Type: Dead :: a -> Vitality a b
+ Fold.Shortcut.Type: ShortcutFold :: Vitality x y -> (y -> a -> Vitality x y) -> (x -> b) -> (y -> b) -> ShortcutFold a b
+ Fold.Shortcut.Type: Tenacious :: Will
+ Fold.Shortcut.Type: [extractDead] :: ShortcutFold a b -> x -> b
+ Fold.Shortcut.Type: [extractLive] :: ShortcutFold a b -> y -> b
+ Fold.Shortcut.Type: [initial] :: ShortcutFold a b -> Vitality x y
+ Fold.Shortcut.Type: [step] :: ShortcutFold a b -> y -> a -> Vitality x y
+ Fold.Shortcut.Type: data ShortcutFold a b
+ Fold.Shortcut.Type: data Vitality a b
+ Fold.Shortcut.Type: data Will
+ Fold.Shortcut.Type: instance GHC.Base.Applicative (Fold.Shortcut.Type.ShortcutFold a)
+ Fold.Shortcut.Type: instance GHC.Base.Functor (Fold.Shortcut.Type.ShortcutFold a)
+ Fold.Shortcut.Type: instance GHC.Base.Monoid b => GHC.Base.Monoid (Fold.Shortcut.Type.ShortcutFold a b)
+ Fold.Shortcut.Type: instance GHC.Base.Semigroup b => GHC.Base.Semigroup (Fold.Shortcut.Type.ShortcutFold a b)
+ Fold.Shortcut.Utilities: demotivate :: ShortcutFold a b -> ShortcutFold a b
+ Fold.ShortcutNonempty: ShortcutNonemptyFold :: (a -> Vitality x y) -> (y -> a -> Vitality x y) -> (x -> b) -> (y -> b) -> ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty: [extractDead] :: ShortcutNonemptyFold a b -> x -> b
+ Fold.ShortcutNonempty: [extractLive] :: ShortcutNonemptyFold a b -> y -> b
+ Fold.ShortcutNonempty: [initial] :: ShortcutNonemptyFold a b -> a -> Vitality x y
+ Fold.ShortcutNonempty: [step] :: ShortcutNonemptyFold a b -> y -> a -> Vitality x y
+ Fold.ShortcutNonempty: all :: (a -> Bool) -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty: and :: ShortcutNonemptyFold Bool Bool
+ Fold.ShortcutNonempty: any :: (a -> Bool) -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty: data ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty: demotivate :: ShortcutNonemptyFold a b -> ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty: effectfulFold :: EffectfulFold Identity a b -> ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty: element :: Eq a => a -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty: elementIndex :: Eq a => a -> ShortcutNonemptyFold a (Maybe Natural)
+ Fold.ShortcutNonempty: find :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe a)
+ Fold.ShortcutNonempty: findIndex :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe Natural)
+ Fold.ShortcutNonempty: first :: ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: fold :: Fold a b -> ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty: index :: Natural -> ShortcutNonemptyFold a (Maybe a)
+ Fold.ShortcutNonempty: last :: ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: length :: ShortcutNonemptyFold a Natural
+ Fold.ShortcutNonempty: list :: ShortcutNonemptyFold a [a]
+ Fold.ShortcutNonempty: lookup :: Eq a => a -> ShortcutNonemptyFold (a, b) (Maybe b)
+ Fold.ShortcutNonempty: magma :: (a -> a -> a) -> ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: maximum :: Ord a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: maximumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: mean :: Fractional a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: minimum :: Ord a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: minimumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: monoid :: Monoid a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: nonemptyFold :: NonemptyFold a b -> ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty: notElement :: Eq a => a -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty: or :: ShortcutNonemptyFold Bool Bool
+ Fold.ShortcutNonempty: product :: Num a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: reverseList :: ShortcutNonemptyFold a [a]
+ Fold.ShortcutNonempty: run :: ShortcutNonemptyFold a b -> NonEmpty a -> b
+ Fold.ShortcutNonempty: semigroup :: Semigroup a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: shortcutFold :: ShortcutFold a b -> ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty: standardDeviation :: Floating a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: sum :: Num a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty: variance :: Fractional a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Conversion: effectfulFold :: EffectfulFold Identity a b -> ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty.Conversion: fold :: Fold a b -> ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty.Conversion: nonemptyFold :: NonemptyFold a b -> ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty.Conversion: shortcutFold :: ShortcutFold a b -> ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty.Examples: all :: (a -> Bool) -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty.Examples: and :: ShortcutNonemptyFold Bool Bool
+ Fold.ShortcutNonempty.Examples: any :: (a -> Bool) -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty.Examples: element :: Eq a => a -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty.Examples: elementIndex :: Eq a => a -> ShortcutNonemptyFold a (Maybe Natural)
+ Fold.ShortcutNonempty.Examples: find :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe a)
+ Fold.ShortcutNonempty.Examples: findIndex :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe Natural)
+ Fold.ShortcutNonempty.Examples: first :: ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: index :: Natural -> ShortcutNonemptyFold a (Maybe a)
+ Fold.ShortcutNonempty.Examples: last :: ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: length :: ShortcutNonemptyFold a Natural
+ Fold.ShortcutNonempty.Examples: list :: ShortcutNonemptyFold a [a]
+ Fold.ShortcutNonempty.Examples: lookup :: Eq a => a -> ShortcutNonemptyFold (a, b) (Maybe b)
+ Fold.ShortcutNonempty.Examples: magma :: (a -> a -> a) -> ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: maximum :: Ord a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: maximumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: mean :: Fractional a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: minimum :: Ord a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: minimumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: monoid :: Monoid a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: notElement :: Eq a => a -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty.Examples: or :: ShortcutNonemptyFold Bool Bool
+ Fold.ShortcutNonempty.Examples: product :: Num a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: reverseList :: ShortcutNonemptyFold a [a]
+ Fold.ShortcutNonempty.Examples: semigroup :: Semigroup a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: standardDeviation :: Floating a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: sum :: Num a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples: variance :: Fractional a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: all :: (a -> Bool) -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty.Examples.Boring: and :: ShortcutNonemptyFold Bool Bool
+ Fold.ShortcutNonempty.Examples.Boring: any :: (a -> Bool) -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty.Examples.Boring: element :: Eq a => a -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty.Examples.Boring: elementIndex :: Eq a => a -> ShortcutNonemptyFold a (Maybe Natural)
+ Fold.ShortcutNonempty.Examples.Boring: find :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe a)
+ Fold.ShortcutNonempty.Examples.Boring: findIndex :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe Natural)
+ Fold.ShortcutNonempty.Examples.Boring: index :: Natural -> ShortcutNonemptyFold a (Maybe a)
+ Fold.ShortcutNonempty.Examples.Boring: last :: ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: length :: ShortcutNonemptyFold a Natural
+ Fold.ShortcutNonempty.Examples.Boring: list :: ShortcutNonemptyFold a [a]
+ Fold.ShortcutNonempty.Examples.Boring: lookup :: Eq a => a -> ShortcutNonemptyFold (a, b) (Maybe b)
+ Fold.ShortcutNonempty.Examples.Boring: magma :: (a -> a -> a) -> ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: maximum :: Ord a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: maximumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: mean :: Fractional a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: minimum :: Ord a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: minimumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: monoid :: Monoid a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: notElement :: Eq a => a -> ShortcutNonemptyFold a Bool
+ Fold.ShortcutNonempty.Examples.Boring: or :: ShortcutNonemptyFold Bool Bool
+ Fold.ShortcutNonempty.Examples.Boring: product :: Num a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: reverseList :: ShortcutNonemptyFold a [a]
+ Fold.ShortcutNonempty.Examples.Boring: semigroup :: Semigroup a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: standardDeviation :: Floating a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: sum :: Num a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Boring: variance :: Fractional a => ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Examples.Interesting: first :: ShortcutNonemptyFold a a
+ Fold.ShortcutNonempty.Run: run :: ShortcutNonemptyFold a b -> NonEmpty a -> b
+ Fold.ShortcutNonempty.Type: Alive :: Will -> b -> Vitality a b
+ Fold.ShortcutNonempty.Type: Ambivalent :: Will
+ Fold.ShortcutNonempty.Type: Dead :: a -> Vitality a b
+ Fold.ShortcutNonempty.Type: ShortcutNonemptyFold :: (a -> Vitality x y) -> (y -> a -> Vitality x y) -> (x -> b) -> (y -> b) -> ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty.Type: Tenacious :: Will
+ Fold.ShortcutNonempty.Type: [extractDead] :: ShortcutNonemptyFold a b -> x -> b
+ Fold.ShortcutNonempty.Type: [extractLive] :: ShortcutNonemptyFold a b -> y -> b
+ Fold.ShortcutNonempty.Type: [initial] :: ShortcutNonemptyFold a b -> a -> Vitality x y
+ Fold.ShortcutNonempty.Type: [step] :: ShortcutNonemptyFold a b -> y -> a -> Vitality x y
+ Fold.ShortcutNonempty.Type: data ShortcutNonemptyFold a b
+ Fold.ShortcutNonempty.Type: data Vitality a b
+ Fold.ShortcutNonempty.Type: data Will
+ Fold.ShortcutNonempty.Type: instance GHC.Base.Applicative (Fold.ShortcutNonempty.Type.ShortcutNonemptyFold a)
+ Fold.ShortcutNonempty.Type: instance GHC.Base.Functor (Fold.ShortcutNonempty.Type.ShortcutNonemptyFold a)
+ Fold.ShortcutNonempty.Type: instance GHC.Base.Monoid b => GHC.Base.Monoid (Fold.ShortcutNonempty.Type.ShortcutNonemptyFold a b)
+ Fold.ShortcutNonempty.Type: instance GHC.Base.Semigroup b => GHC.Base.Semigroup (Fold.ShortcutNonempty.Type.ShortcutNonemptyFold a b)
+ Fold.ShortcutNonempty.Utilities: demotivate :: ShortcutNonemptyFold a b -> ShortcutNonemptyFold a b
+ Fold.Types: data ShortcutFold a b
+ Fold.Types: data ShortcutNonemptyFold a b
- Fold: all :: (a -> Bool) -> Fold a Bool
+ Fold: all :: (a -> Bool) -> ShortcutFold a Bool
- Fold: and :: Fold Bool Bool
+ Fold: and :: ShortcutFold Bool Bool
- Fold: any :: (a -> Bool) -> Fold a Bool
+ Fold: any :: (a -> Bool) -> ShortcutFold a Bool
- Fold: element :: Eq a => a -> Fold a Bool
+ Fold: element :: Eq a => a -> ShortcutFold a Bool
- Fold: elementIndex :: Eq a => a -> Fold a (Maybe Natural)
+ Fold: elementIndex :: Eq a => a -> ShortcutFold a (Maybe Natural)
- Fold: find :: (a -> Bool) -> Fold a (Maybe a)
+ Fold: find :: (a -> Bool) -> ShortcutFold a (Maybe a)
- Fold: findIndex :: (a -> Bool) -> Fold a (Maybe Natural)
+ Fold: findIndex :: (a -> Bool) -> ShortcutFold a (Maybe Natural)
- Fold: first :: NonemptyFold a a
+ Fold: first :: ShortcutNonemptyFold a a
- Fold: index :: Natural -> Fold a (Maybe a)
+ Fold: index :: Natural -> ShortcutFold a (Maybe a)
- Fold: lookup :: Eq a => a -> Fold (a, b) (Maybe b)
+ Fold: lookup :: Eq a => a -> ShortcutFold (a, b) (Maybe b)
- Fold: notElement :: Eq a => a -> Fold a Bool
+ Fold: notElement :: Eq a => a -> ShortcutFold a Bool
- Fold: null :: Fold a Bool
+ Fold: null :: ShortcutFold a Bool
- Fold: or :: Fold Bool Bool
+ Fold: or :: ShortcutFold Bool Bool
Files
- changelog.md +10/−0
- gambler.cabal +29/−6
- license.txt +1/−1
- readme.md +151/−17
- source/Fold.hs +9/−4
- source/Fold/Effectful.hs +10/−16
- source/Fold/Effectful/Conversion.hs +8/−0
- source/Fold/Effectful/Examples.hs +15/−24
- source/Fold/Effectful/Examples/Boring.hs +149/−0
- source/Fold/Effectful/Examples/Interesting.hs +25/−0
- source/Fold/Effectful/Nonempty.hs +0/−50
- source/Fold/Effectful/Pure.hs +0/−108
- source/Fold/Nonempty.hs +8/−11
- source/Fold/Nonempty/Conversion.hs +19/−2
- source/Fold/Nonempty/Examples.hs +8/−58
- source/Fold/Nonempty/Examples/Boring.hs +110/−0
- source/Fold/Nonempty/Examples/Interesting.hs +62/−0
- source/Fold/Nonempty/Pure.hs +0/−107
- source/Fold/Pure.hs +4/−7
- source/Fold/Pure/Conversion.hs +31/−1
- source/Fold/Pure/Examples.hs +5/−141
- source/Fold/Pure/Examples/Boring.hs +106/−0
- source/Fold/Pure/Examples/Interesting.hs +72/−0
- source/Fold/Pure/Nonempty.hs +0/−49
- source/Fold/Shortcut.hs +28/−0
- source/Fold/Shortcut/Conversion.hs +45/−0
- source/Fold/Shortcut/Examples.hs +16/−0
- source/Fold/Shortcut/Examples/Boring.hs +98/−0
- source/Fold/Shortcut/Examples/Interesting.hs +118/−0
- source/Fold/Shortcut/Run.hs +13/−0
- source/Fold/Shortcut/Type.hs +64/−0
- source/Fold/Shortcut/Utilities.hs +19/−0
- source/Fold/ShortcutNonempty.hs +28/−0
- source/Fold/ShortcutNonempty/Conversion.hs +51/−0
- source/Fold/ShortcutNonempty/Examples.hs +16/−0
- source/Fold/ShortcutNonempty/Examples/Boring.hs +147/−0
- source/Fold/ShortcutNonempty/Examples/Interesting.hs +15/−0
- source/Fold/ShortcutNonempty/Run.hs +16/−0
- source/Fold/ShortcutNonempty/Type.hs +64/−0
- source/Fold/ShortcutNonempty/Utilities.hs +19/−0
- source/Fold/Types.hs +1/−1
- source/Strict.hs +35/−1
- test/Main.hs +4/−0
- test/Spec/Effectful.hs +9/−0
- test/Spec/Pure.hs +21/−0
- test/Spec/Shortcut.hs +81/−0
- test/Spec/ShortcutNonempty.hs +59/−0
changelog.md view
@@ -1,3 +1,13 @@+## 0.1.0.0 (2023-02-20)++Adds `ShortcutFold` and `ShortcutNonemptyFold`.++The following have changed from `Fold` to `ShortcutFold`:+`and`, `or`, `all`, `any`, `element`, `notElement`, `find`,+`lookup`, `index`, `findIndex`, `elementIndex`, `null`.++`first` has changed from `NonemptyFold` to `ShortcutNonemptyFold`.+ ## 0.0.1.0 (2023-02-20) Add `Fold.Nonempty.effectfulFold`; this was already available from
gambler.cabal view
@@ -1,7 +1,7 @@ cabal-version: 3.0 name: gambler-version: 0.0.1.0+version: 0.1.0.0 category: Streaming synopsis: Composable, streaming, and efficient left folds@@ -14,7 +14,7 @@ license: BSD-3-Clause license-file: license.txt-copyright: 2013-2016 Gabriella Gonzalez+copyright: 2013-2016 Gabriella Gonzalez, 2023 Mission Valley Software LLC bug-reports: https://github.com/typeclasses/gambler/issues @@ -25,6 +25,7 @@ ghc-options: -Wall default-extensions:+ ApplicativeDo NoImplicitPrelude build-depends: , base ^>= 4.16 || ^>= 4.17@@ -39,7 +40,8 @@ Fold.Pure Fold.Pure.Conversion Fold.Pure.Examples- Fold.Pure.Nonempty+ Fold.Pure.Examples.Interesting+ Fold.Pure.Examples.Boring Fold.Pure.Run Fold.Pure.Type Fold.Pure.Utilities@@ -47,8 +49,8 @@ Fold.Effectful Fold.Effectful.Conversion Fold.Effectful.Examples- Fold.Effectful.Nonempty- Fold.Effectful.Pure+ Fold.Effectful.Examples.Interesting+ Fold.Effectful.Examples.Boring Fold.Effectful.Run Fold.Effectful.Type Fold.Effectful.Utilities@@ -56,11 +58,30 @@ Fold.Nonempty Fold.Nonempty.Conversion Fold.Nonempty.Examples- Fold.Nonempty.Pure+ Fold.Nonempty.Examples.Interesting+ Fold.Nonempty.Examples.Boring Fold.Nonempty.Run Fold.Nonempty.Type Fold.Nonempty.Utilities + Fold.Shortcut+ Fold.Shortcut.Run+ Fold.Shortcut.Type+ Fold.Shortcut.Examples+ Fold.Shortcut.Examples.Interesting+ Fold.Shortcut.Examples.Boring+ Fold.Shortcut.Conversion+ Fold.Shortcut.Utilities++ Fold.ShortcutNonempty+ Fold.ShortcutNonempty.Run+ Fold.ShortcutNonempty.Type+ Fold.ShortcutNonempty.Examples+ Fold.ShortcutNonempty.Examples.Interesting+ Fold.ShortcutNonempty.Examples.Boring+ Fold.ShortcutNonempty.Conversion+ Fold.ShortcutNonempty.Utilities+ other-modules: Strict @@ -73,6 +94,8 @@ Spec.Pure Spec.Nonempty Spec.Effectful+ Spec.Shortcut+ Spec.ShortcutNonempty ghc-options: -threaded default-extensions:
license.txt view
@@ -1,4 +1,4 @@-Copyright (c) 2013-2016 Gabriella Gonzalez+Copyright (c) 2013-2016 Gabriella Gonzalez, 2023 Mission Valley Software LLC All rights reserved. Redistribution and use in source and binary forms, with or without modification,
readme.md view
@@ -10,7 +10,7 @@ — *The Gambler* by Don Schlitz, popularized by Kenny Rogers -## Intro to Fold+## Fold The `foldl'` function in the `base` package is used when we want a strictly evaluated result from traversing a list.@@ -33,7 +33,7 @@ ```haskell data Fold a b = Fold { initial :: b- , step :: b -> a -> b }+ , step :: b -> a -> b } ``` Or, better yet, we can use a trick to turn the datatype into a `Functor` (which@@ -42,7 +42,7 @@ ```haskell data Fold a b = forall x. Fold { initial :: x- , step :: x -> a -> x+ , step :: x -> a -> x , extract :: x -> b } ``` @@ -71,7 +71,7 @@ dreamt of in this package. -## Intro to NonemptyFold+## NonemptyFold There are some kinds of folding that only work if the input it nonempty. Suppose, for example, we want the greatest of all the items. If there are no@@ -81,7 +81,7 @@ ```haskell data NonemptyFold a b = forall x. NonemptyFold { initial :: a -> x- , step :: x -> a -> x+ , step :: x -> a -> x , extract :: x -> b } ``` @@ -99,7 +99,7 @@ accommodate the possibility of empty input. -## Intro to EffectfulFold+## EffectfulFold There is a related function in `base` that does the same thing as `foldl'` but in a monadic context:@@ -127,7 +127,7 @@ ```haskell data EffectfulFold m a b = forall x. EffectfulFold { initial :: m x- , step :: x -> a -> m x+ , step :: x -> a -> m x , extract :: x -> m b } ``` @@ -135,7 +135,7 @@ `Fold.Effectful.fold`. -## The Applicative instances+## Applicative instances The `Fold` and `EffectfulFold` applicatives are great for computing multiple folds over a collection in one pass over the data. For example, suppose that you want@@ -158,7 +158,7 @@ With `gambler`, we can instead write: ```haskell-import qualified Fold+import qualified Fold.Pure as Fold sumAndLength :: Num a => [a] -> (a, Natural) sumAndLength = Fold.runFold $ (,) <$> Fold.sum <*> Fold.length@@ -167,6 +167,133 @@ This achieves the same result using constant space. +## ShortcutFold++Operations like `sum` and `length` inherently require the entirety of the input.+But suppose, for example, we want to know whether a list contains a particular+item. Once we find the item, we can stop looking. For situations like this, we+have `ShortcutFold`.++```haskell+data ShortcutFold a b = forall x y. ShortcutFold+ { initial :: Vitality x y+ , step :: y -> a -> Vitality x y+ , extractDead :: x -> b+ , extractLive :: y -> b+ }+```++```haskell+data Vitality a b = Dead a | Alive Will b+```++```haskell+data Will = Ambivalent | Tenacious+```++If `initial` or `step` returns a `Dead` result, then no further input can be fed+into the fold. The `Will` type will be discussed below.++Example of testing for the presence of a particular element:++```ghci+λ> import qualified Fold.Shortcut as Fold++λ> Fold.run (Fold.element 'a') "back"+True++λ> Fold.run (Fold.element 'a') "front"+False+```++By running a shortcut fold over a partially-defined input list, we can verify+that evaluation does indeed halt once the element is found:++```haskell+λ> Fold.run (Fold.element 'a') ("ba" ++ undefined)+True+```++## ShortcutNonemptyFold++The non-empty variant of `ShortcutFold` is `ShortcutNonemptyFold`.++```haskell+data ShortcutNonemptyFold a b = forall x y. ShortcutNonemptyFold+ { initial :: a -> Vitality x y+ , step :: y -> a -> Vitality x y+ , extractDead :: x -> b+ , extractLive :: y -> b+ }+```++Like `NonemptyFold`, the only thing we've changed here is to add an `a`+parameter to the `initial` field.+++## Shortcutting Applicative instances++Just like `Fold`, `ShortcutFold` can be combined in an applicative manner and+the input is traversed in a single pass.++```haskell+λ> import qualified Fold.Shortcut as Fold++λ> Fold.run ((,) <$> Fold.index 4 <*> Fold.index 2) "abcdef"+(Just 'e',Just 'c')+```++With an applicative composition, traversal continues as long as any of the+constituent parts is alive and still expecting more input. In the example above,+`index 2` becomes dead after the third character (`'c'`), but the composition+stays alive until the fifth character (`'e'`) results in the completion of+`index 4`.++A fold indicates that it is finished by returning `Dead` as its `Vitality`. But+there is one more subtlety: When a fold is `Alive`, it can further specify+whether it *wants* to keep receiving more items or not. This disposition is+called `Will`. A `Tenacious` will means that the fold wants more input; an+`Ambivalent` will mean the fold *can* accept more input, but doesn't care. The+difference is that tenacious folds keep larger applicative compositions alive,+whereas ambivalent folds do not. Shortcut folds are tagged in the documentation+as "(ambivalent)" or "(tenacious)".++One example of an ambivalent shortcut fold is `length`. We see in the example+below that the length fold keeps counting only as long as the other fold it+is composed with still needs input.++```haskell+λ> Fold.run ((,) <$> Fold.length <*> Fold.element 'e') "abcdef"+(5,True)++λ> Fold.run ((,) <$> Fold.length <*> Fold.element 'z') "abcdef"+(6,False)+```++Consider another example:++```haskell+λ> f1 = ((,) <$> Fold.length <*> Fold.element 'c')++λ> f2 = ((,) <$> Fold.length <*> Fold.element 'e')++λ> Fold.run ((,) <$> f1 <*> f2) "abcdef"+((5,True),(5,True))+```++The example above composes four folds (two `length` folds and two `element`+folds). Notice that both of the length folds returned 5 because they keep+running until the entire fold stops, regardless of the way they're composed. We+can avoid this behavior with the `demotivate` utility, which stops a fold from+being so eager. A demotivated fold will stop receiving input when all of its+components are either dead or ambivalent.++```haskell+λ> Fold.run ((,) <$> Fold.demotivate f1 <*> Fold.demotivate f2) "abcdef"+((3,True),(5,True))+```++ ## Quick start To get quickly playing around with `gambler`, launch GHCi using `cabal`:@@ -175,29 +302,36 @@ cabal repl --build-depends gambler ``` -The example from the previous section can be run as follows:+Import the module corresponding to one of the varieties of fold: ```haskell-λ> import qualified Fold+λ> import qualified Fold.Pure as Fold ``` +And enjoy.+ ```haskell λ> Fold.runFold ((,) <$> Fold.sum <*> Fold.length) [1..1000000] (500000500000,1000000) ``` -## Related packages+## Authors -This `gambler` package is mostly a copy of [foldl], with some features removed-to minimize its dependency set. What remains in `gambler` is essentially the-same as what can be found in `foldl` version `1.4.13`, subject only to-reorganization, renaming, and minor modifications.+This package began as mostly a copy of [foldl], with some features removed to+minimize its dependency set. What remained in `gambler-0.0` was essentially+the same as what could be found in `foldl-1.4.13`, subject only to+reorganization, renaming, and minor modifications. The `Fold`, `EffectfulFold`,+and `NonemptyFold` types are the work of Gabriella Gonzalez. - [foldl]: https://hackage.haskell.org/package/foldl+`ShortcutFold` and `ShortcutNonemptyFold` were added by Mission Valley Software+in `gambler-0.1`. ## Future plans Once the `Foldable1` class has been added to `base`, the type of `Fold.Nonempty.run` may be generalized to accommodate it.+++ [foldl]: https://hackage.haskell.org/package/foldl
source/Fold.hs view
@@ -1,7 +1,8 @@ module Fold ( {- * Fold types -} Fold (Fold), NonemptyFold (NonemptyFold),- EffectfulFold (EffectfulFold),+ EffectfulFold (EffectfulFold), ShortcutFold (ShortcutFold),+ ShortcutNonemptyFold (ShortcutNonemptyFold), Vitality (..), Will (..), {- * Running -} runFold, runNonemptyFold, runEffectfulFold, {- * Search -} element, notElement, find, lookup, {- * Arithmetic folds -} sum, product, mean, variance, standardDeviation,@@ -22,10 +23,14 @@ import Fold.Effectful.Type import Fold.Nonempty.Type import Fold.Pure.Type+import Fold.Shortcut.Type+import Fold.ShortcutNonempty.Type -import Fold.Effectful.Examples-import Fold.Nonempty.Examples hiding (list, reverseList)-import Fold.Pure.Examples+import Fold.Effectful.Examples.Interesting+import Fold.Nonempty.Examples.Interesting hiding (list, reverseList)+import Fold.Pure.Examples.Interesting+import Fold.Shortcut.Examples.Interesting+import Fold.ShortcutNonempty.Examples.Interesting import Fold.Effectful.Utilities
source/Fold/Effectful.hs view
@@ -5,21 +5,17 @@ {- * Run -} run, {- * Examples -}- {- ** General -} effect, effectMonoid,- {- ** Pure -}- {- *** Monoid -} monoid,- {- *** Length -} null, length,- {- *** Boolean -} and, or, all, any,- {- *** Numeric -} sum, product, mean, variance, standardDeviation,- {- *** Search -} element, notElement, find, lookup,- {- *** Index -} index, findIndex, elementIndex,- {- *** List -} list, reverseList,- {- ** Nonempty -}- {- *** General -} magma, semigroup,- {- *** Endpoints -} first, last,- {- *** Extrema -} maximum, minimum, maximumBy, minimumBy,+ {- ** General -} effect, effectMonoid, magma, semigroup, monoid,+ {- ** Endpoints -} first, last,+ {- ** Extrema -} maximum, minimum, maximumBy, minimumBy,+ {- ** Length -} null, length,+ {- ** Boolean -} and, or, all, any,+ {- ** Numeric -} sum, product, mean, variance, standardDeviation,+ {- ** Search -} element, notElement, find, lookup,+ {- ** Index -} index, findIndex, elementIndex,+ {- ** List -} list, reverseList, - {- * Conversion -} fold, nonemptyFold,+ {- * Conversion -} fold, nonemptyFold, shortcutFold, shortcutNonemptyFold, {- * Utilities -} hoist, duplicate, premap, prefilter, drop, )@@ -27,8 +23,6 @@ import Fold.Effectful.Conversion import Fold.Effectful.Examples-import Fold.Effectful.Nonempty-import Fold.Effectful.Pure import Fold.Effectful.Run import Fold.Effectful.Type import Fold.Effectful.Utilities
source/Fold/Effectful/Conversion.hs view
@@ -6,6 +6,8 @@ import Control.Monad (Monad) import Data.Maybe (Maybe) import Fold.Nonempty.Type (NonemptyFold)+import Fold.Shortcut.Type (ShortcutFold)+import Fold.ShortcutNonempty.Type (ShortcutNonemptyFold) import qualified Control.Applicative as Applicative import qualified Fold.Pure.Conversion as Pure@@ -23,3 +25,9 @@ returns 'Data.Maybe.Nothing' when there are no inputs -} nonemptyFold :: Monad m => NonemptyFold a b -> EffectfulFold m a (Maybe b) nonemptyFold x = fold (Pure.nonemptyFold x)++shortcutFold :: Monad m => ShortcutFold a b -> EffectfulFold m a b+shortcutFold x = fold (Pure.shortcutFold x)++shortcutNonemptyFold :: Monad m => ShortcutNonemptyFold a b -> EffectfulFold m a (Maybe b)+shortcutNonemptyFold x = fold (Pure.shortcutNonemptyFold x)
source/Fold/Effectful/Examples.hs view
@@ -1,25 +1,16 @@--- | Some interesting examples of effectful folds-module Fold.Effectful.Examples where--import Fold.Effectful.Type--import Control.Monad (Monad)-import Data.Functor (void)-import Data.Monoid (Monoid, mempty)-import Data.Semigroup ((<>))-import Prelude (($!))--import qualified Control.Applicative as Applicative--{-| Performs an action for each input, discarding the result -}-effect :: Monad m => (a -> m b) -> EffectfulFold m a ()-effect f = effectMonoid (\a -> void (f a))+module Fold.Effectful.Examples+ (+ {- * General -} effect, effectMonoid, magma, semigroup, monoid,+ {- * Endpoints -} first, last,+ {- * Extrema -} maximum, minimum, maximumBy, minimumBy,+ {- * Length -} null, length,+ {- * Boolean -} and, or, all, any,+ {- * Numeric -} sum, product, mean, variance, standardDeviation,+ {- * Search -} element, notElement, find, lookup,+ {- * Index -} index, findIndex, elementIndex,+ {- * List -} list, reverseList,+ )+ where -{-| Performs an action for each input, monoidally combining the results-from all the actions. -}-effectMonoid :: (Monoid w, Monad m) => (a -> m w) -> EffectfulFold m a w-effectMonoid act = EffectfulFold- { initial = Applicative.pure mempty- , step = \m a -> do{ m' <- act a; Applicative.pure $! (<>) m m' }- , extract = Applicative.pure- }+import Fold.Effectful.Examples.Interesting+import Fold.Effectful.Examples.Boring
+ source/Fold/Effectful/Examples/Boring.hs view
@@ -0,0 +1,149 @@+-- | Folds of other types trivially lifted into 'EffectfulFold'+module Fold.Effectful.Examples.Boring+ (+ {- * Monoid -} monoid,+ {- * Length -} null, length,+ {- * Boolean -} and, or, all, any,+ {- * Numeric -} sum, product, mean, variance, standardDeviation,+ {- * Search -} element, notElement, find, lookup,+ {- * Index -} index, findIndex, elementIndex,+ {- * List -} list, reverseList,+ {- * General -} magma, semigroup,+ {- * Endpoints -} first, last,+ {- * Extrema -} maximum, minimum, maximumBy, minimumBy,+ )+ where++import Control.Monad (Monad)+import Data.Maybe (Maybe)+import Data.Ord (Ord, Ordering)+import Data.Semigroup (Semigroup)+import Fold.Effectful.Type (EffectfulFold)+import Data.Bool (Bool)+import Data.Eq (Eq)+import Data.Monoid (Monoid)+import Numeric.Natural (Natural)+import Prelude (Floating, Fractional, Num)++import qualified Fold.Pure.Examples.Interesting as Pure+import qualified Fold.Nonempty.Examples.Interesting as Nonempty+import qualified Fold.Shortcut.Examples.Interesting as Shortcut+import qualified Fold.ShortcutNonempty.Examples.Interesting as ShortcutNonempty+import qualified Fold.Effectful.Conversion as Convert++{-| Start with the first input, append each new input on the right+with the given function -}+magma :: (a -> a -> a) -> Monad m => EffectfulFold m a (Maybe a)+magma step = Convert.nonemptyFold (Nonempty.magma step)++{-| Append each new input on the right with ('<>') -}+semigroup :: Semigroup a => Monad m => EffectfulFold m a (Maybe a)+semigroup = Convert.nonemptyFold Nonempty.semigroup++{-| The first input -}+first :: Monad m => EffectfulFold m a (Maybe a)+first = Convert.shortcutNonemptyFold ShortcutNonempty.first++{-| The last input -}+last :: Monad m => EffectfulFold m a (Maybe a)+last = Convert.nonemptyFold Nonempty.last++{-| The greatest input -}+maximum :: Ord a => Monad m => EffectfulFold m a (Maybe a)+maximum = Convert.nonemptyFold Nonempty.maximum++{-| The greatest input with respect to the given comparison function -}+maximumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)+maximumBy cmp = Convert.nonemptyFold (Nonempty.maximumBy cmp)++{-| The least input -}+minimum :: Ord a => Monad m => EffectfulFold m a (Maybe a)+minimum = Convert.nonemptyFold Nonempty.minimum++{-| The least input with respect to the given comparison function -}+minimumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)+minimumBy cmp = Convert.nonemptyFold (Nonempty.minimumBy cmp)++{-| Start with 'mempty', append each input on the right with ('<>') -}+monoid :: Monoid a => Monad m => EffectfulFold m a a+monoid = Convert.fold Pure.monoid++{-| 'True' if the input contains no inputs -}+null :: Monad m => EffectfulFold m a Bool+null = Convert.shortcutFold Shortcut.null++{-| The number of inputs -}+length :: Monad m => EffectfulFold m a Natural+length = Convert.fold Pure.length++{-| 'True' if all inputs are 'True' -}+and :: Monad m => EffectfulFold m Bool Bool+and = Convert.shortcutFold Shortcut.and++{-| 'True' if any input is 'True' -}+or :: Monad m => EffectfulFold m Bool Bool+or = Convert.shortcutFold Shortcut.or++{-| 'True' if all inputs satisfy the predicate -}+all :: Monad m => (a -> Bool) -> EffectfulFold m a Bool+all predicate = Convert.shortcutFold (Shortcut.all predicate)++{-| 'True' if any input satisfies the predicate -}+any :: Monad m => (a -> Bool) -> EffectfulFold m a Bool+any predicate = Convert.shortcutFold (Shortcut.any predicate)++{-| Adds the inputs -}+sum :: Num a => Monad m => EffectfulFold m a a+sum = Convert.fold Pure.sum++{-| Multiplies the inputs -}+product :: Num a => Monad m => EffectfulFold m a a+product = Convert.fold Pure.product++{-| Numerically stable arithmetic mean of the inputs -}+mean :: Fractional a => Monad m => EffectfulFold m a a+mean = Convert.fold Pure.mean++{-| Numerically stable (population) variance over the inputs -}+variance :: Fractional a => Monad m => EffectfulFold m a a+variance = Convert.fold Pure.variance++{-| Numerically stable (population) standard deviation over the inputs -}+standardDeviation :: Floating a => Monad m => EffectfulFold m a a+standardDeviation = Convert.fold Pure.standardDeviation++{-| 'True' if any input is equal to the given value -}+element :: Eq a => Monad m => a -> EffectfulFold m a Bool+element a = Convert.shortcutFold (Shortcut.element a)++{-| 'False' if any input is equal to the given value -}+notElement :: Eq a => Monad m => a -> EffectfulFold m a Bool+notElement a = Convert.shortcutFold (Shortcut.notElement a)++{-| The first input that satisfies the predicate, if any -}+find :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe a)+find ok = Convert.shortcutFold (Shortcut.find ok)++{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}+index :: Monad m => Natural -> EffectfulFold m a (Maybe a)+index i = Convert.shortcutFold (Shortcut.index i)++{-| The index of the first input that matches the given value, if any -}+elementIndex :: Eq a => Monad m => a -> EffectfulFold m a (Maybe Natural)+elementIndex a = Convert.shortcutFold (Shortcut.elementIndex a)++{-| The index of the first input that satisfies the predicate, if any -}+findIndex :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe Natural)+findIndex ok = Convert.shortcutFold (Shortcut.findIndex ok)++{-| The @b@ from the first tuple where @a@ equals the given value, if any -}+lookup :: Eq a => Monad m => a -> EffectfulFold m (a, b) (Maybe b)+lookup a = Convert.shortcutFold (Shortcut.lookup a)++{-| All the inputs -}+list :: Monad m => EffectfulFold m a [a]+list = Convert.fold Pure.list++{-| All the inputs in reverse order -}+reverseList :: Monad m => EffectfulFold m a [a]+reverseList = Convert.fold Pure.reverseList
+ source/Fold/Effectful/Examples/Interesting.hs view
@@ -0,0 +1,25 @@+-- | Some interesting examples of effectful folds+module Fold.Effectful.Examples.Interesting where++import Fold.Effectful.Type++import Control.Monad (Monad)+import Data.Functor (void)+import Data.Monoid (Monoid, mempty)+import Data.Semigroup ((<>))+import Prelude (($!))++import qualified Control.Applicative as Applicative++{-| Performs an action for each input, discarding the result -}+effect :: Monad m => (a -> m b) -> EffectfulFold m a ()+effect f = effectMonoid (\a -> void (f a))++{-| Performs an action for each input, monoidally combining the results+from all the actions. -}+effectMonoid :: (Monoid w, Monad m) => (a -> m w) -> EffectfulFold m a w+effectMonoid act = EffectfulFold+ { initial = Applicative.pure mempty+ , step = \m a -> do{ m' <- act a; Applicative.pure $! (<>) m m' }+ , extract = Applicative.pure+ }
− source/Fold/Effectful/Nonempty.hs
@@ -1,50 +0,0 @@--- | Folds from "Fold.Pure.Nonempty" trivially lifted into 'EffectfulFold'-module Fold.Effectful.Nonempty- (- {- * General -} magma, semigroup,- {- * Endpoints -} first, last,- {- * Extrema -} maximum, minimum, maximumBy, minimumBy,- )- where--import Control.Monad (Monad)-import Data.Maybe (Maybe)-import Data.Ord (Ord, Ordering)-import Data.Semigroup (Semigroup)-import Fold.Effectful.Conversion (fold)-import Fold.Effectful.Type (EffectfulFold)--import qualified Fold.Pure.Nonempty as Pure--{-| Start with the first input, append each new input on the right-with the given function -}-magma :: (a -> a -> a) -> Monad m => EffectfulFold m a (Maybe a)-magma step = fold (Pure.magma step)--{-| Append each new input on the right with ('<>') -}-semigroup :: Semigroup a => Monad m => EffectfulFold m a (Maybe a)-semigroup = fold Pure.semigroup--{-| The first input -}-first :: Monad m => EffectfulFold m a (Maybe a)-first = fold Pure.first--{-| The last input -}-last :: Monad m => EffectfulFold m a (Maybe a)-last = fold Pure.last--{-| The greatest input -}-maximum :: Ord a => Monad m => EffectfulFold m a (Maybe a)-maximum = fold Pure.maximum--{-| The greatest input with respect to the given comparison function -}-maximumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)-maximumBy cmp = fold (Pure.maximumBy cmp)--{-| The least input -}-minimum :: Ord a => Monad m => EffectfulFold m a (Maybe a)-minimum = fold Pure.minimum--{-| The least input with respect to the given comparison function -}-minimumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)-minimumBy cmp = fold (Pure.minimumBy cmp)
− source/Fold/Effectful/Pure.hs
@@ -1,108 +0,0 @@--- | Folds from "Fold.Pure.Examples" trivially lifted into 'EffectfulFold'-module Fold.Effectful.Pure- (- {- * Monoid -} monoid,- {- * Length -} null, length,- {- * Boolean -} and, or, all, any,- {- * Numeric -} sum, product, mean, variance, standardDeviation,- {- * Search -} element, notElement, find, lookup,- {- * Index -} index, findIndex, elementIndex,- {- * List -} list, reverseList,- )- where--import Control.Monad (Monad)-import Data.Bool (Bool)-import Data.Eq (Eq)-import Data.Maybe (Maybe)-import Data.Monoid (Monoid)-import Fold.Effectful.Conversion (fold)-import Fold.Effectful.Type (EffectfulFold)-import Numeric.Natural (Natural)-import Prelude (Floating, Fractional, Num)--import qualified Fold.Pure.Examples as Pure--{-| Start with 'mempty', append each input on the right with ('<>') -}-monoid :: Monoid a => Monad m => EffectfulFold m a a-monoid = fold Pure.monoid--{-| 'True' if the input contains no inputs -}-null :: Monad m => EffectfulFold m a Bool-null = fold Pure.null--{-| The number of inputs -}-length :: Monad m => EffectfulFold m a Natural-length = fold Pure.length--{-| 'True' if all inputs are 'True' -}-and :: Monad m => EffectfulFold m Bool Bool-and = fold Pure.and--{-| 'True' if any input is 'True' -}-or :: Monad m => EffectfulFold m Bool Bool-or = fold Pure.or--{-| 'True' if all inputs satisfy the predicate -}-all :: Monad m => (a -> Bool) -> EffectfulFold m a Bool-all predicate = fold (Pure.all predicate)--{-| 'True' if any input satisfies the predicate -}-any :: Monad m => (a -> Bool) -> EffectfulFold m a Bool-any predicate = fold (Pure.any predicate)--{-| Adds the inputs -}-sum :: Num a => Monad m => EffectfulFold m a a-sum = fold Pure.sum--{-| Multiplies the inputs -}-product :: Num a => Monad m => EffectfulFold m a a-product = fold Pure.product--{-| Numerically stable arithmetic mean of the inputs -}-mean :: Fractional a => Monad m => EffectfulFold m a a-mean = fold Pure.mean--{-| Numerically stable (population) variance over the inputs -}-variance :: Fractional a => Monad m => EffectfulFold m a a-variance = fold Pure.variance--{-| Numerically stable (population) standard deviation over the inputs -}-standardDeviation :: Floating a => Monad m => EffectfulFold m a a-standardDeviation = fold Pure.standardDeviation--{-| 'True' if any input is equal to the given value -}-element :: Eq a => Monad m => a -> EffectfulFold m a Bool-element a = fold (Pure.element a)--{-| 'False' if any input is equal to the given value -}-notElement :: Eq a => Monad m => a -> EffectfulFold m a Bool-notElement a = fold (Pure.notElement a)--{-| The first input that satisfies the predicate, if any -}-find :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe a)-find ok = fold (Pure.find ok)--{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}-index :: Monad m => Natural -> EffectfulFold m a (Maybe a)-index i = fold (Pure.index i)--{-| The index of the first input that matches the given value, if any -}-elementIndex :: Eq a => Monad m => a -> EffectfulFold m a (Maybe Natural)-elementIndex a = fold (Pure.elementIndex a)--{-| The index of the first input that satisfies the predicate, if any -}-findIndex :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe Natural)-findIndex ok = fold (Pure.findIndex ok)--{-| The @b@ from the first tuple where @a@ equals the given value, if any -}-lookup :: Eq a => Monad m => a -> EffectfulFold m (a, b) (Maybe b)-lookup a = fold (Pure.lookup a)--{-| All the inputs -}-list :: Monad m => EffectfulFold m a [a]-list = fold Pure.list--{-| All the inputs in reverse order -}-reverseList :: Monad m => EffectfulFold m a [a]-reverseList = fold Pure.reverseList
source/Fold/Nonempty.hs view
@@ -5,19 +5,17 @@ {- * Run -} run, {- * Examples -}- {- ** General -} magma, semigroup,+ {- ** General -} magma, semigroup, monoid, {- ** Endpoints -} first, last, {- ** Extrema -} maximum, minimum, maximumBy, minimumBy,- {- ** Pure -}- {- *** Monoid -} monoid,- {- *** Length -} null, length,- {- *** Boolean -} and, or, all, any,- {- *** Numeric -} sum, product, mean, variance, standardDeviation,- {- *** Search -} element, notElement, find, lookup,- {- *** Index -} index, findIndex, elementIndex,- {- *** List -} list, reverseList,+ {- ** Length -} length,+ {- ** Boolean -} and, or, all, any,+ {- ** Numeric -} sum, product, mean, variance, standardDeviation,+ {- ** Search -} element, notElement, find, lookup,+ {- ** Index -} index, findIndex, elementIndex,+ {- ** List -} list, reverseList, - {- * Conversion -} fold, effectfulFold,+ {- * Conversion -} fold, effectfulFold, shortcutFold, shortcutNonemptyFold, {- * Utilities -} duplicate, premap, nest, )@@ -25,7 +23,6 @@ import Fold.Nonempty.Conversion import Fold.Nonempty.Examples-import Fold.Nonempty.Pure hiding (list, reverseList) import Fold.Nonempty.Run import Fold.Nonempty.Type import Fold.Nonempty.Utilities
source/Fold/Nonempty/Conversion.hs view
@@ -5,11 +5,14 @@ import Fold.Effectful.Type (EffectfulFold) import Fold.Pure.Type (Fold (Fold))+import Fold.ShortcutNonempty.Type (ShortcutNonemptyFold (ShortcutNonemptyFold))+import Fold.Shortcut.Type (ShortcutFold)+import Strict (Vitality (Dead, Alive))+import Data.Functor.Identity (Identity) import qualified Fold.Pure.Type as Fold import qualified Fold.Pure.Conversion as Fold.Conversion--import Data.Functor.Identity (Identity)+import qualified Fold.ShortcutNonempty.Type as ShortcutNonempty {-| Turn a regular fold that allows empty input into a fold that requires at least one input -}@@ -21,3 +24,17 @@ one input -} effectfulFold :: EffectfulFold Identity a b -> NonemptyFold a b effectfulFold x = fold (Fold.Conversion.effectfulFold x)++shortcutFold :: ShortcutFold a b -> NonemptyFold a b+shortcutFold x = fold (Fold.Conversion.shortcutFold x)++shortcutNonemptyFold :: ShortcutNonemptyFold a b -> NonemptyFold a b+shortcutNonemptyFold ShortcutNonemptyFold{ ShortcutNonempty.step,+ ShortcutNonempty.initial, ShortcutNonempty.extractDead, ShortcutNonempty.extractLive } =+ NonemptyFold+ { initial = initial+ , step = \s -> case s of { Dead _ -> \_ -> s; Alive _ x -> step x }+ , extract = \s -> case s of+ Dead x -> extractDead x+ Alive _ x -> extractLive x+ }
source/Fold/Nonempty/Examples.hs view
@@ -1,66 +1,16 @@ module Fold.Nonempty.Examples (- {- * General -} magma, semigroup,+ {- * General -} magma, semigroup, monoid, {- * Endpoints -} first, last, {- * Extrema -} maximum, minimum, maximumBy, minimumBy,+ {- * Length -} length,+ {- * Boolean -} and, or, all, any,+ {- * Numeric -} sum, product, mean, variance, standardDeviation,+ {- * Search -} element, notElement, find, lookup,+ {- * Index -} index, findIndex, elementIndex, {- * List -} list, reverseList, ) where -import Fold.Nonempty.Type--import Data.Function (id, const, flip, (.))-import Data.List.NonEmpty (NonEmpty ((:|)))-import Data.Ord (Ord, Ordering (GT), max, min)-import Data.Semigroup (Semigroup, (<>))--import qualified Strict--{-| Start with the first input, append each new input on the right-with the given function -}-magma :: (a -> a -> a) -> NonemptyFold a a-magma step = NonemptyFold{ initial = id, step, extract = id }--{-| Append each new input on the right with ('<>') -}-semigroup :: Semigroup a => NonemptyFold a a-semigroup = magma (<>)--{-| The first input -}-first :: NonemptyFold a a-first = magma const--{-| The last input -}-last :: NonemptyFold a a-last = magma (flip const)--{-| The greatest input -}-maximum :: Ord a => NonemptyFold a a-maximum = magma max--{-| The greatest input with respect to the given comparison function -}-maximumBy :: (a -> a -> Ordering) -> NonemptyFold a a-maximumBy cmp = magma (\x y -> case cmp x y of { GT -> x; _ -> y })--{-| The least input -}-minimum :: Ord a => NonemptyFold a a-minimum = magma min--{-| The least input with respect to the given comparison function -}-minimumBy :: (a -> a -> Ordering) -> NonemptyFold a a-minimumBy cmp = magma (\x y -> case cmp x y of { GT -> y; _ -> x })--{-| All the inputs -}-list :: NonemptyFold a (NonEmpty a)-list = NonemptyFold- { initial = \a -> Strict.Tuple2 a id- , step = \(Strict.Tuple2 a0 x) a -> Strict.Tuple2 a0 (x . (a :))- , extract = \(Strict.Tuple2 a0 x) -> a0 :| (x [])- }--{-| All the inputs in reverse order -}-reverseList :: NonemptyFold a (NonEmpty a)-reverseList = NonemptyFold- { initial = (:| [])- , step = \(b :| x) a -> a :| b : x- , extract = id- }+import Fold.Nonempty.Examples.Interesting+import Fold.Nonempty.Examples.Boring hiding (list, reverseList)
+ source/Fold/Nonempty/Examples/Boring.hs view
@@ -0,0 +1,110 @@+-- | Folds of other types trivially lifted into 'NonemptyFold'+module Fold.Nonempty.Examples.Boring+ (+ {- * Endpoints -} first,+ {- * Monoid -} monoid,+ {- * Length -} length,+ {- * Boolean -} and, or, all, any,+ {- * Numeric -} sum, product, mean, variance, standardDeviation,+ {- * Search -} element, notElement, find, lookup,+ {- * Index -} index, findIndex, elementIndex,+ {- * List -} list, reverseList,+ )+ where++import Data.Bool (Bool)+import Data.Eq (Eq)+import Data.Maybe (Maybe)+import Data.Monoid (Monoid)+import Fold.Nonempty.Type (NonemptyFold)+import Numeric.Natural (Natural)+import Prelude (Floating, Fractional, Num)++import qualified Fold.Nonempty.Conversion as Convert+import qualified Fold.Pure.Examples.Interesting as Pure+import qualified Fold.Shortcut.Examples.Interesting as Shortcut+import qualified Fold.ShortcutNonempty.Examples as ShortcutNonempty++{-| The first input -}+first :: NonemptyFold a a+first = Convert.shortcutNonemptyFold ShortcutNonempty.first++{-| Start with 'mempty', append each input on the right with ('<>') -}+monoid :: Monoid a => NonemptyFold a a+monoid = Convert.fold Pure.monoid++{-| The number of inputs -}+length :: NonemptyFold a Natural+length = Convert.fold Pure.length++{-| 'True' if all inputs are 'True' -}+and :: NonemptyFold Bool Bool+and = Convert.shortcutFold Shortcut.and++{-| 'True' if any input is 'True' -}+or :: NonemptyFold Bool Bool+or = Convert.shortcutFold Shortcut.or++{-| 'True' if all inputs satisfy the predicate -}+all :: (a -> Bool) -> NonemptyFold a Bool+all predicate = Convert.shortcutFold (Shortcut.all predicate)++{-| 'True' if any input satisfies the predicate -}+any :: (a -> Bool) -> NonemptyFold a Bool+any predicate = Convert.shortcutFold (Shortcut.any predicate)++{-| Adds the inputs -}+sum :: Num a => NonemptyFold a a+sum = Convert.fold Pure.sum++{-| Multiplies the inputs -}+product :: Num a => NonemptyFold a a+product = Convert.fold Pure.product++{-| Numerically stable arithmetic mean of the inputs -}+mean :: Fractional a => NonemptyFold a a+mean = Convert.fold Pure.mean++{-| Numerically stable (population) variance over the inputs -}+variance :: Fractional a => NonemptyFold a a+variance = Convert.fold Pure.variance++{-| Numerically stable (population) standard deviation over the inputs -}+standardDeviation :: Floating a => NonemptyFold a a+standardDeviation = Convert.fold Pure.standardDeviation++{-| 'True' if any input is equal to the given value -}+element :: Eq a => a -> NonemptyFold a Bool+element a = Convert.shortcutFold (Shortcut.element a)++{-| 'False' if any input is equal to the given value -}+notElement :: Eq a => a -> NonemptyFold a Bool+notElement a = Convert.shortcutFold (Shortcut.notElement a)++{-| The first input that satisfies the predicate, if any -}+find :: (a -> Bool) -> NonemptyFold a (Maybe a)+find ok = Convert.shortcutFold (Shortcut.find ok)++{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}+index :: Natural -> NonemptyFold a (Maybe a)+index i = Convert.shortcutFold (Shortcut.index i)++{-| The index of the first input that matches the given value, if any -}+elementIndex :: Eq a => a -> NonemptyFold a (Maybe Natural)+elementIndex a = Convert.shortcutFold (Shortcut.elementIndex a)++{-| The index of the first input that satisfies the predicate, if any -}+findIndex :: (a -> Bool) -> NonemptyFold a (Maybe Natural)+findIndex ok = Convert.shortcutFold (Shortcut.findIndex ok)++{-| The @b@ from the first tuple where @a@ equals the given value, if any -}+lookup :: Eq a => a -> NonemptyFold (a, b) (Maybe b)+lookup a = Convert.shortcutFold (Shortcut.lookup a)++{-| All the inputs -}+list :: NonemptyFold a [a]+list = Convert.fold Pure.list++{-| All the inputs in reverse order -}+reverseList :: NonemptyFold a [a]+reverseList = Convert.fold Pure.reverseList
+ source/Fold/Nonempty/Examples/Interesting.hs view
@@ -0,0 +1,62 @@+module Fold.Nonempty.Examples.Interesting+ (+ {- * General -} magma, semigroup,+ {- * Endpoints -} last,+ {- * Extrema -} maximum, minimum, maximumBy, minimumBy,+ {- * List -} list, reverseList,+ )+ where++import Fold.Nonempty.Type++import Data.Function (id, const, flip, (.))+import Data.List.NonEmpty (NonEmpty ((:|)))+import Data.Ord (Ord, Ordering (GT), max, min)+import Data.Semigroup (Semigroup, (<>))++import qualified Strict++{-| Start with the first input, append each new input on the right+with the given function -}+magma :: (a -> a -> a) -> NonemptyFold a a+magma step = NonemptyFold{ initial = id, step, extract = id }++{-| Append each new input on the right with ('<>') -}+semigroup :: Semigroup a => NonemptyFold a a+semigroup = magma (<>)++{-| The last input -}+last :: NonemptyFold a a+last = magma (flip const)++{-| The greatest input -}+maximum :: Ord a => NonemptyFold a a+maximum = magma max++{-| The greatest input with respect to the given comparison function -}+maximumBy :: (a -> a -> Ordering) -> NonemptyFold a a+maximumBy cmp = magma (\x y -> case cmp x y of { GT -> x; _ -> y })++{-| The least input -}+minimum :: Ord a => NonemptyFold a a+minimum = magma min++{-| The least input with respect to the given comparison function -}+minimumBy :: (a -> a -> Ordering) -> NonemptyFold a a+minimumBy cmp = magma (\x y -> case cmp x y of { GT -> y; _ -> x })++{-| All the inputs -}+list :: NonemptyFold a (NonEmpty a)+list = NonemptyFold+ { initial = \a -> Strict.Tuple2 a id+ , step = \(Strict.Tuple2 a0 x) a -> Strict.Tuple2 a0 (x . (a :))+ , extract = \(Strict.Tuple2 a0 x) -> a0 :| (x [])+ }++{-| All the inputs in reverse order -}+reverseList :: NonemptyFold a (NonEmpty a)+reverseList = NonemptyFold+ { initial = (:| [])+ , step = \(b :| x) a -> a :| b : x+ , extract = id+ }
− source/Fold/Nonempty/Pure.hs
@@ -1,107 +0,0 @@--- | Folds from "Fold.Pure.Examples" trivially lifted into 'NonemptyFold'-module Fold.Nonempty.Pure- (- {- * Monoid -} monoid,- {- * Length -} null, length,- {- * Boolean -} and, or, all, any,- {- * Numeric -} sum, product, mean, variance, standardDeviation,- {- * Search -} element, notElement, find, lookup,- {- * Index -} index, findIndex, elementIndex,- {- * List -} list, reverseList,- )- where--import qualified Fold.Pure.Examples as Pure--import Data.Bool (Bool)-import Data.Eq (Eq)-import Data.Maybe (Maybe)-import Data.Monoid (Monoid)-import Fold.Nonempty.Conversion (fold)-import Fold.Nonempty.Type (NonemptyFold)-import Numeric.Natural (Natural)-import Prelude (Floating, Fractional, Num)--{-| Start with 'mempty', append each input on the right with ('<>') -}-monoid :: Monoid a => NonemptyFold a a-monoid = fold Pure.monoid--{-| 'True' if the input contains no inputs -}-null :: NonemptyFold a Bool-null = fold Pure.null--{-| The number of inputs -}-length :: NonemptyFold a Natural-length = fold Pure.length--{-| 'True' if all inputs are 'True' -}-and :: NonemptyFold Bool Bool-and = fold Pure.and--{-| 'True' if any input is 'True' -}-or :: NonemptyFold Bool Bool-or = fold Pure.or--{-| 'True' if all inputs satisfy the predicate -}-all :: (a -> Bool) -> NonemptyFold a Bool-all predicate = fold (Pure.all predicate)--{-| 'True' if any input satisfies the predicate -}-any :: (a -> Bool) -> NonemptyFold a Bool-any predicate = fold (Pure.any predicate)--{-| Adds the inputs -}-sum :: Num a => NonemptyFold a a-sum = fold Pure.sum--{-| Multiplies the inputs -}-product :: Num a => NonemptyFold a a-product = fold Pure.product--{-| Numerically stable arithmetic mean of the inputs -}-mean :: Fractional a => NonemptyFold a a-mean = fold Pure.mean--{-| Numerically stable (population) variance over the inputs -}-variance :: Fractional a => NonemptyFold a a-variance = fold Pure.variance--{-| Numerically stable (population) standard deviation over the inputs -}-standardDeviation :: Floating a => NonemptyFold a a-standardDeviation = fold Pure.standardDeviation--{-| 'True' if any input is equal to the given value -}-element :: Eq a => a -> NonemptyFold a Bool-element a = fold (Pure.element a)--{-| 'False' if any input is equal to the given value -}-notElement :: Eq a => a -> NonemptyFold a Bool-notElement a = fold (Pure.notElement a)--{-| The first input that satisfies the predicate, if any -}-find :: (a -> Bool) -> NonemptyFold a (Maybe a)-find ok = fold (Pure.find ok)--{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}-index :: Natural -> NonemptyFold a (Maybe a)-index i = fold (Pure.index i)--{-| The index of the first input that matches the given value, if any -}-elementIndex :: Eq a => a -> NonemptyFold a (Maybe Natural)-elementIndex a = fold (Pure.elementIndex a)--{-| The index of the first input that satisfies the predicate, if any -}-findIndex :: (a -> Bool) -> NonemptyFold a (Maybe Natural)-findIndex ok = fold (Pure.findIndex ok)--{-| The @b@ from the first tuple where @a@ equals the given value, if any -}-lookup :: Eq a => a -> NonemptyFold (a, b) (Maybe b)-lookup a = fold (Pure.lookup a)--{-| All the inputs -}-list :: NonemptyFold a [a]-list = fold Pure.list--{-| All the inputs in reverse order -}-reverseList :: NonemptyFold a [a]-reverseList = fold Pure.reverseList
source/Fold/Pure.hs view
@@ -5,19 +5,17 @@ {- * Run -} run, scan, prescan, postscan, {- * Examples -}- {- ** Monoid -} monoid,+ {- ** General -} magma, semigroup, monoid,+ {- ** Endpoints -} first, last,+ {- ** Extrema -} maximum, minimum, maximumBy, minimumBy, {- ** Length -} null, length, {- ** Boolean -} and, or, all, any, {- ** Numeric -} sum, product, mean, variance, standardDeviation, {- ** Search -} element, notElement, find, lookup, {- ** Index -} index, findIndex, elementIndex, {- ** List -} list, reverseList,- {- ** Nonempty -}- {- *** General -} magma, semigroup,- {- *** Endpoints -} first, last,- {- *** Extrema -} maximum, minimum, maximumBy, minimumBy, - {- * Conversion -} effectfulFold, nonemptyFold,+ {- * Conversion -} effectfulFold, nonemptyFold, shortcutFold, shortcutNonemptyFold, {- * Utilities -} duplicate, premap, prefilter, predropWhile, drop, nest, )@@ -25,7 +23,6 @@ import Fold.Pure.Conversion import Fold.Pure.Examples-import Fold.Pure.Nonempty import Fold.Pure.Run import Fold.Pure.Type import Fold.Pure.Utilities
source/Fold/Pure/Conversion.hs view
@@ -4,14 +4,19 @@ import Fold.Pure.Type import Data.Function (($))-import Data.Functor ((<$>))+import Data.Functor ((<$>), (<&>)) import Data.Functor.Identity (Identity, runIdentity) import Data.Maybe (Maybe) import Fold.Effectful.Type (EffectfulFold (EffectfulFold)) import Fold.Nonempty.Type (NonemptyFold (NonemptyFold))+import Fold.Shortcut.Type (ShortcutFold (ShortcutFold))+import Fold.ShortcutNonempty.Type (ShortcutNonemptyFold (ShortcutNonemptyFold))+import Strict (Vitality (Dead, Alive)) import qualified Fold.Effectful.Type as Effectful import qualified Fold.Nonempty.Type as Nonempty+import qualified Fold.ShortcutNonempty.Type as ShortcutNonempty+import qualified Fold.Shortcut.Type as Shortcut import qualified Strict {-| Turn an effectful fold into a pure fold -}@@ -35,4 +40,29 @@ Strict.Nothing -> initial a Strict.Just x -> step x a , extract = \xm -> extract <$> Strict.lazy xm+ }++shortcutFold :: ShortcutFold a b -> Fold a b+shortcutFold ShortcutFold{+ Shortcut.initial, Shortcut.step, Shortcut.extractLive, Shortcut.extractDead } =+ Fold+ { initial = initial+ , step = \s -> case s of { Dead _ -> \_ -> s; Alive _ x -> step x }+ , extract = \s -> case s of+ Dead x -> extractDead x+ Alive _ x -> extractLive x+ }++shortcutNonemptyFold :: ShortcutNonemptyFold a b -> Fold a (Maybe b)+shortcutNonemptyFold ShortcutNonemptyFold{ ShortcutNonempty.initial,+ ShortcutNonempty.step, ShortcutNonempty.extractLive, ShortcutNonempty.extractDead } =+ Fold+ { initial = Strict.Nothing+ , step = \xm a -> case xm of+ Strict.Nothing -> Strict.Just (initial a)+ Strict.Just (Alive _ x) -> Strict.Just (step x a)+ Strict.Just (Dead _) -> xm+ , extract = \xm -> Strict.lazy xm <&> \s -> case s of+ Dead x -> extractDead x+ Alive _ x -> extractLive x }
source/Fold/Pure/Examples.hs view
@@ -1,6 +1,8 @@ module Fold.Pure.Examples (- {- * Monoid -} monoid,+ {- * General -} magma, semigroup, monoid,+ {- * Endpoints -} first, last,+ {- * Extrema -} maximum, minimum, maximumBy, minimumBy, {- * Length -} null, length, {- * Boolean -} and, or, all, any, {- * Numeric -} sum, product, mean, variance, standardDeviation,@@ -10,143 +12,5 @@ ) where -import Fold.Pure.Type--import Data.Bool (Bool (False, True), (&&), (||))-import Data.Eq (Eq, (/=), (==))-import Data.Function (id, ($), (.))-import Data.Functor ((<$>))-import Data.Maybe (Maybe)-import Data.Monoid (Monoid, mempty)-import Data.Semigroup ((<>))-import Numeric.Natural (Natural)-import Prelude (Floating, Fractional, Num, sqrt, (*), (+), (-), (/))--import qualified Strict--{-| Start with 'mempty', append each input on the right with ('<>') -}-monoid :: Monoid a => Fold a a-monoid = Fold{ initial = mempty, step = (<>), extract = id }--{-| 'True' if the input contains no inputs -}-null :: Fold a Bool-null = Fold{ initial = True, step = \_ _ -> False, extract = id }--{-| The number of inputs -}-length :: Fold a Natural-length = Fold{ initial = 0, step = \n _ -> n + 1, extract = id }--{-| 'True' if all inputs are 'True' -}-and :: Fold Bool Bool-and = Fold{ initial = True, step = (&&), extract = id }--{-| 'True' if any input is 'True' -}-or :: Fold Bool Bool-or = Fold{ initial = False, step = (||), extract = id }--{-| 'True' if all inputs satisfy the predicate -}-all :: (a -> Bool) -> Fold a Bool-all predicate =- Fold{ initial = True, step = \x a -> x && predicate a, extract = id }--{-| 'True' if any input satisfies the predicate -}-any :: (a -> Bool) -> Fold a Bool-any predicate =- Fold{ initial = False, step = \x a -> x || predicate a, extract = id }--{-| Adds the inputs -}-sum :: Num a => Fold a a-sum = Fold{ initial = 0, step = (+), extract = id }--{-| Multiplies the inputs -}-product :: Num a => Fold a a-product = Fold{ initial = 1, step = (*), extract = id }--{-| Numerically stable arithmetic mean of the inputs -}-mean :: Fractional a => Fold a a-mean = Fold- { initial = Strict.Tuple2 0 0- , step = \(Strict.Tuple2 x n) y ->- let n' = n + 1 in- Strict.Tuple2 (x + (y - x) / n') n'- , extract = \(Strict.Tuple2 x _) -> x- }--{-| Numerically stable (population) variance over the inputs -}-variance :: Fractional a => Fold a a-variance = Fold- { initial = Strict.Tuple3 0 0 0- , step = \(Strict.Tuple3 n mean_ m2) x ->- let- n' = n + 1- mean' = (n * mean_ + x) / (n + 1)- delta = x - mean_- m2' = m2 + delta * delta * n / (n + 1)- in- Strict.Tuple3 n' mean' m2'- , extract = \(Strict.Tuple3 n _ m2) -> m2 / n- }--{-| Numerically stable (population) standard deviation over the inputs -}-standardDeviation :: Floating a => Fold a a-standardDeviation = sqrt <$> variance--{-| 'True' if any input is equal to the given value -}-element :: Eq a => a -> Fold a Bool-element a = any (a ==)--{-| 'False' if any input is equal to the given value -}-notElement :: Eq a => a -> Fold a Bool-notElement a = all (a /=)--{-| The first input that satisfies the predicate, if any -}-find :: (a -> Bool) -> Fold a (Maybe a)-find ok = Fold- { initial = Strict.Nothing- , step = \x a -> case x of- Strict.Nothing -> if ok a then Strict.Just a else Strict.Nothing- _ -> x- , extract = Strict.lazy- }--{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}-index :: Natural -> Fold a (Maybe a)-index i = Fold- { initial = Strict.Left 0- , step = \x a -> case x of- Strict.Left j -> if i == j then Strict.Right a else Strict.Left (j + 1)- _ -> x- , extract = Strict.hush- }--{-| The index of the first input that matches the given value, if any -}-elementIndex :: Eq a => a -> Fold a (Maybe Natural)-elementIndex a = findIndex (a ==)--{-| The index of the first input that satisfies the predicate, if any -}-findIndex :: (a -> Bool) -> Fold a (Maybe Natural)-findIndex ok = Fold- { initial = Strict.Left 0- , step = \x a -> case x of- Strict.Left i -> if ok a then Strict.Right i else Strict.Left (i + 1)- _ -> x- , extract = Strict.hush- }--{-| The @b@ from the first tuple where @a@ equals the given value, if any -}-lookup :: Eq a => a -> Fold (a, b) (Maybe b)-lookup a0 = Fold- { initial = Strict.Nothing- , step = \x (a, b) -> case x of- Strict.Nothing -> if a == a0 then Strict.Just b else Strict.Nothing- _ -> x- , extract = Strict.lazy- }--{-| All the inputs -}-list :: Fold a [a]-list = Fold{ initial = id, step = \x a -> x . (a :), extract = ($ []) }--{-| All the inputs in reverse order -}-reverseList :: Fold a [a]-reverseList = Fold{ initial = [], step = \x a -> a : x, extract = id }+import Fold.Pure.Examples.Interesting+import Fold.Pure.Examples.Boring
+ source/Fold/Pure/Examples/Boring.hs view
@@ -0,0 +1,106 @@+-- | Folds of other types trivially lifted into 'Fold'+module Fold.Pure.Examples.Boring+ (+ {- * Length -} null,+ {- * General -} magma, semigroup,+ {- * Endpoints -} first, last,+ {- * Extrema -} maximum, minimum, maximumBy, minimumBy,+ {- * Boolean -} and, or, all, any,+ {- * Search -} element, notElement, find, lookup,+ {- * Index -} index, findIndex, elementIndex,+ )+ where++import Data.Maybe (Maybe)+import Data.Ord (Ord, Ordering)+import Data.Semigroup (Semigroup)+import Fold.Pure.Type (Fold)+import Data.Bool (Bool)+import Data.Eq (Eq)+import Numeric.Natural (Natural)++import qualified Fold.Pure.Conversion as Convert+import qualified Fold.Nonempty.Examples.Interesting as Nonempty+import qualified Fold.ShortcutNonempty.Examples.Interesting as ShortcutNonempty+import qualified Fold.Shortcut.Examples.Interesting as Shortcut++{-| 'True' if the input contains no inputs -}+null :: Fold a Bool+null = Convert.shortcutFold Shortcut.null++{-| Start with the first input, append each new input on the right+with the given function -}+magma :: (a -> a -> a) -> Fold a (Maybe a)+magma step = Convert.nonemptyFold (Nonempty.magma step)++{-| Append each new input on the right with ('<>') -}+semigroup :: Semigroup a => Fold a (Maybe a)+semigroup = Convert.nonemptyFold Nonempty.semigroup++{-| The first input -}+first :: Fold a (Maybe a)+first = Convert.shortcutNonemptyFold ShortcutNonempty.first++{-| The last input -}+last :: Fold a (Maybe a)+last = Convert.nonemptyFold Nonempty.last++{-| The greatest input -}+maximum :: Ord a => Fold a (Maybe a)+maximum = Convert.nonemptyFold Nonempty.maximum++{-| The greatest input with respect to the given comparison function -}+maximumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)+maximumBy cmp = Convert.nonemptyFold (Nonempty.maximumBy cmp)++{-| The least input -}+minimum :: Ord a => Fold a (Maybe a)+minimum = Convert.nonemptyFold Nonempty.minimum++{-| The least input with respect to the given comparison function -}+minimumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)+minimumBy cmp = Convert.nonemptyFold (Nonempty.minimumBy cmp)++{-| 'True' if all inputs are 'True' -}+and :: Fold Bool Bool+and = Convert.shortcutFold Shortcut.and++{-| 'True' if any input is 'True' -}+or :: Fold Bool Bool+or = Convert.shortcutFold Shortcut.or++{-| 'True' if all inputs satisfy the predicate -}+all :: (a -> Bool) -> Fold a Bool+all predicate = Convert.shortcutFold (Shortcut.all predicate)++{-| 'True' if any input satisfies the predicate -}+any :: (a -> Bool) -> Fold a Bool+any predicate = Convert.shortcutFold (Shortcut.any predicate)++{-| 'True' if any input is equal to the given value -}+element :: Eq a => a -> Fold a Bool+element a = Convert.shortcutFold (Shortcut.element a)++{-| 'False' if any input is equal to the given value -}+notElement :: Eq a => a -> Fold a Bool+notElement a = Convert.shortcutFold (Shortcut.notElement a)++{-| The first input that satisfies the predicate, if any -}+find :: (a -> Bool) -> Fold a (Maybe a)+find ok = Convert.shortcutFold (Shortcut.find ok)++{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}+index :: Natural -> Fold a (Maybe a)+index i = Convert.shortcutFold (Shortcut.index i)++{-| The index of the first input that matches the given value, if any -}+elementIndex :: Eq a => a -> Fold a (Maybe Natural)+elementIndex a = Convert.shortcutFold (Shortcut.elementIndex a)++{-| The index of the first input that satisfies the predicate, if any -}+findIndex :: (a -> Bool) -> Fold a (Maybe Natural)+findIndex ok = Convert.shortcutFold (Shortcut.findIndex ok)++{-| The @b@ from the first tuple where @a@ equals the given value, if any -}+lookup :: Eq a => a -> Fold (a, b) (Maybe b)+lookup a0 = Convert.shortcutFold (Shortcut.lookup a0)
+ source/Fold/Pure/Examples/Interesting.hs view
@@ -0,0 +1,72 @@+module Fold.Pure.Examples.Interesting+ (+ {- * Monoid -} monoid,+ {- * Length -} length,+ {- * Numeric -} sum, product, mean, variance, standardDeviation,+ {- * List -} list, reverseList,+ )+ where++import Fold.Pure.Type++import Data.Function (id, ($), (.))+import Data.Functor ((<$>))+import Data.Monoid (Monoid, mempty)+import Data.Semigroup ((<>))+import Numeric.Natural (Natural)+import Prelude (Floating, Fractional, Num, sqrt, (*), (+), (-), (/))++import qualified Strict++{-| Start with 'mempty', append each input on the right with ('<>') -}+monoid :: Monoid a => Fold a a+monoid = Fold{ initial = mempty, step = (<>), extract = id }++{-| The number of inputs -}+length :: Fold a Natural+length = Fold{ initial = 0, step = \n _ -> n + 1, extract = id }++{-| Adds the inputs -}+sum :: Num a => Fold a a+sum = Fold{ initial = 0, step = (+), extract = id }++{-| Multiplies the inputs -}+product :: Num a => Fold a a+product = Fold{ initial = 1, step = (*), extract = id }++{-| Numerically stable arithmetic mean of the inputs -}+mean :: Fractional a => Fold a a+mean = Fold+ { initial = Strict.Tuple2 0 0+ , step = \(Strict.Tuple2 x n) y ->+ let n' = n + 1 in+ Strict.Tuple2 (x + (y - x) / n') n'+ , extract = \(Strict.Tuple2 x _) -> x+ }++{-| Numerically stable (population) variance over the inputs -}+variance :: Fractional a => Fold a a+variance = Fold+ { initial = Strict.Tuple3 0 0 0+ , step = \(Strict.Tuple3 n mean_ m2) x ->+ let+ n' = n + 1+ mean' = (n * mean_ + x) / (n + 1)+ delta = x - mean_+ m2' = m2 + delta * delta * n / (n + 1)+ in+ Strict.Tuple3 n' mean' m2'+ , extract = \(Strict.Tuple3 n _ m2) -> m2 / n+ }++{-| Numerically stable (population) standard deviation over the inputs -}+standardDeviation :: Floating a => Fold a a+standardDeviation = sqrt <$> variance++{-| All the inputs -}+list :: Fold a [a]+list = Fold{ initial = id, step = \x a -> x . (a :), extract = ($ []) }++{-| All the inputs in reverse order -}+reverseList :: Fold a [a]+reverseList = Fold{ initial = [], step = \x a -> a : x, extract = id }
− source/Fold/Pure/Nonempty.hs
@@ -1,49 +0,0 @@--- | Folds from "Fold.Nonempty.Examples" trivially lifted into 'Fold'-module Fold.Pure.Nonempty- (- {- * General -} magma, semigroup,- {- * Endpoints -} first, last,- {- * Extrema -} maximum, minimum, maximumBy, minimumBy,- )- where--import Data.Maybe (Maybe)-import Data.Ord (Ord, Ordering)-import Data.Semigroup (Semigroup)-import Fold.Pure.Conversion (nonemptyFold)-import Fold.Pure.Type (Fold)--import qualified Fold.Nonempty.Examples as Nonempty--{-| Start with the first input, append each new input on the right-with the given function -}-magma :: (a -> a -> a) -> Fold a (Maybe a)-magma step = nonemptyFold (Nonempty.magma step)--{-| Append each new input on the right with ('<>') -}-semigroup :: Semigroup a => Fold a (Maybe a)-semigroup = nonemptyFold Nonempty.semigroup--{-| The first input -}-first :: Fold a (Maybe a)-first = nonemptyFold Nonempty.first--{-| The last input -}-last :: Fold a (Maybe a)-last = nonemptyFold Nonempty.last--{-| The greatest input -}-maximum :: Ord a => Fold a (Maybe a)-maximum = nonemptyFold Nonempty.maximum--{-| The greatest input with respect to the given comparison function -}-maximumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)-maximumBy cmp = nonemptyFold (Nonempty.maximumBy cmp)--{-| The least input -}-minimum :: Ord a => Fold a (Maybe a)-minimum = nonemptyFold Nonempty.minimum--{-| The least input with respect to the given comparison function -}-minimumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)-minimumBy cmp = nonemptyFold (Nonempty.minimumBy cmp)
+ source/Fold/Shortcut.hs view
@@ -0,0 +1,28 @@+module Fold.Shortcut+ (+ {- * Type -} ShortcutFold (..),++ {- * Run -} run,++ {- * Examples -}+ {- ** General -} magma, semigroup, monoid,+ {- ** Endpoints -} first, last,+ {- ** Extrema -} maximum, minimum, maximumBy, minimumBy,+ {- ** Length -} null, length,+ {- ** Boolean -} and, or, all, any,+ {- ** Numeric -} sum, product, mean, variance, standardDeviation,+ {- ** Search -} element, notElement, find, lookup,+ {- ** Index -} index, findIndex, elementIndex,+ {- ** List -} list, reverseList,++ {- * Conversion -} fold, effectfulFold, nonemptyFold, shortcutNonemptyFold,++ {- * Utilities -} demotivate,+ )+ where++import Fold.Shortcut.Conversion+import Fold.Shortcut.Examples+import Fold.Shortcut.Run+import Fold.Shortcut.Type+import Fold.Shortcut.Utilities
+ source/Fold/Shortcut/Conversion.hs view
@@ -0,0 +1,45 @@+module Fold.Shortcut.Conversion where++import Fold.Shortcut.Type++import Data.Functor ((<$>))+import Data.Functor.Identity (Identity)+import Data.Maybe (Maybe (Just))+import Fold.Effectful.Type (EffectfulFold)+import Fold.Nonempty.Type (NonemptyFold)+import Fold.Pure.Type (Fold (Fold))+import Fold.ShortcutNonempty.Type (ShortcutNonemptyFold (ShortcutNonemptyFold))+import Data.Void (absurd)++import qualified Fold.Pure.Conversion as Fold+import qualified Fold.Pure.Type as Fold+import qualified Fold.ShortcutNonempty.Type as ShortcutNonempty+import qualified Strict++fold :: Fold a b -> ShortcutFold a b+fold+ Fold{ Fold.initial, Fold.step, Fold.extract } =+ ShortcutFold+ { initial = Alive Ambivalent initial+ , step = \x a -> Alive Ambivalent (step x a)+ , extractDead = absurd+ , extractLive = extract+ }++effectfulFold :: EffectfulFold Identity a b -> ShortcutFold a b+effectfulFold x = fold (Fold.effectfulFold x)++nonemptyFold :: NonemptyFold a b -> ShortcutFold a (Maybe b)+nonemptyFold x = fold (Fold.nonemptyFold x)++shortcutNonemptyFold :: ShortcutNonemptyFold a b -> ShortcutFold a (Maybe b)+shortcutNonemptyFold ShortcutNonemptyFold{ ShortcutNonempty.initial,+ ShortcutNonempty.step, ShortcutNonempty.extractDead, ShortcutNonempty.extractLive } =+ ShortcutFold+ { initial = Alive Tenacious Strict.Nothing+ , step = \xm a -> Strict.Just <$> case xm of+ Strict.Nothing -> initial a+ Strict.Just x -> step x a+ , extractDead = \x -> Just (extractDead x)+ , extractLive = \xm -> extractLive <$> Strict.lazy xm+ }
+ source/Fold/Shortcut/Examples.hs view
@@ -0,0 +1,16 @@+module Fold.Shortcut.Examples+ (+ {- * General -} magma, semigroup, monoid,+ {- * Endpoints -} first, last,+ {- * Extrema -} maximum, minimum, maximumBy, minimumBy,+ {- * Length -} null, length,+ {- * Boolean -} and, or, all, any,+ {- * Numeric -} sum, product, mean, variance, standardDeviation,+ {- * Search -} element, notElement, find, lookup,+ {- * Index -} index, findIndex, elementIndex,+ {- * List -} list, reverseList,+ )+ where++import Fold.Shortcut.Examples.Interesting+import Fold.Shortcut.Examples.Boring
+ source/Fold/Shortcut/Examples/Boring.hs view
@@ -0,0 +1,98 @@+-- | Folds of other types trivially lifted into 'Shortcut'+module Fold.Shortcut.Examples.Boring+ (+ {- * Arithmetic folds -} sum, product, mean, variance, standardDeviation,+ {- * Counting inputs -} length,+ {- * Min/max -} maximum, minimum, maximumBy, minimumBy,+ {- * First/last -} first, last,+ {- * General folds -} magma, semigroup, monoid,+ {- * List folds -} list, reverseList,+ )+ where++import Data.Maybe (Maybe)+import Fold.Shortcut.Type (ShortcutFold)+import Data.Semigroup (Semigroup)+import Data.Ord (Ord, Ordering (GT), max, min)+import Data.Monoid (Monoid)+import Prelude (Floating, Fractional, Num)+import Numeric.Natural (Natural)++import qualified Fold.ShortcutNonempty.Examples.Interesting as ShortcutNonempty+import qualified Fold.Nonempty.Examples.Interesting as Nonempty+import qualified Fold.Pure.Examples.Interesting as Fold+import qualified Fold.Shortcut.Conversion as Convert++{-| The first input (tenacious) -}+first :: ShortcutFold a (Maybe a)+first = Convert.shortcutNonemptyFold ShortcutNonempty.first++{-| Start with the first input, append each new input on the right+ with the given function (ambivalent) -}+magma :: (a -> a -> a) -> ShortcutFold a (Maybe a)+magma step = Convert.nonemptyFold (Nonempty.magma step)++{-| Append each new input on the right with '<>' (ambivalent) -}+semigroup :: Semigroup a => ShortcutFold a (Maybe a)+semigroup = Convert.nonemptyFold Nonempty.semigroup++{-| The last input (ambivalent) -}+last :: ShortcutFold a (Maybe a)+last = Convert.nonemptyFold Nonempty.last++{-| The greatest input (ambivalent) -}+maximum :: Ord a => ShortcutFold a (Maybe a)+maximum = magma max++{-| The greatest input with respect to the given comparison function+ (ambivalent) -}+maximumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)+maximumBy cmp = magma (\x y -> case cmp x y of { GT -> x; _ -> y })++{-| The least input (ambivalent) -}+minimum :: Ord a => ShortcutFold a (Maybe a)+minimum = magma min++{-| The least input with respect to the given comparison function+ (ambivalent) -}+minimumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)+minimumBy cmp = magma (\x y -> case cmp x y of { GT -> y; _ -> x })++{-| All the inputs (ambivalent) -}+list :: ShortcutFold a [a]+list = Convert.fold Fold.list++{-| All the inputs in reverse order (ambivalent) -}+reverseList :: ShortcutFold a [a]+reverseList = Convert.fold Fold.reverseList++{-| Start with 'mempty', append each input on the right with '<>'+ (ambivalent)-}+monoid :: Monoid a => ShortcutFold a a+monoid = Convert.fold Fold.monoid++{-| The number of inputs (ambivalent) -}+length :: ShortcutFold a Natural+length = Convert.fold Fold.length++{-| Adds the inputs (ambivalent) -}+sum :: Num a => ShortcutFold a a+sum = Convert.fold Fold.sum++{-| Multiplies the inputs (ambivalent) -}+product :: Num a => ShortcutFold a a+product = Convert.fold Fold.product++{-| Numerically stable arithmetic mean of the inputs (ambivalent) -}+mean :: Fractional a => ShortcutFold a a+mean = Convert.fold Fold.mean++{-| Numerically stable (population) variance over the+ inputs (ambivalent) -}+variance :: Fractional a => ShortcutFold a a+variance = Convert.fold Fold.variance++{-| Numerically stable (population) standard deviation over the+ inputs (ambivalent) -}+standardDeviation :: Floating a => ShortcutFold a a+standardDeviation = Convert.fold Fold.standardDeviation
+ source/Fold/Shortcut/Examples/Interesting.hs view
@@ -0,0 +1,118 @@+module Fold.Shortcut.Examples.Interesting+ (+ {- * Length -} null,+ {- * Boolean -} and, or, all, any,+ {- * Search -} element, notElement, find, lookup,+ {- * Index -} index, findIndex, elementIndex,+ )+ where++import Fold.Shortcut.Type++import Control.Applicative (liftA2)+import Data.Bool (Bool (False, True))+import Data.Eq (Eq, (/=), (==))+import Data.Functor (($>), (<&>))+import Data.Maybe (Maybe (Just, Nothing))+import Numeric.Natural (Natural)+import Prelude ((-))+import Fold.Shortcut.Conversion (fold)+import Fold.Shortcut.Utilities (demotivate)++import qualified Fold.Pure.Examples.Interesting as Fold++{-| 'True' if the input contains no inputs (tenacious) -}+null :: ShortcutFold a Bool+null = ShortcutFold+ { initial = Alive Tenacious ()+ , step = \() _ -> Dead ()+ , extractLive = \() -> True+ , extractDead = \() -> False+ }++{-| 'True' if all inputs are 'True' (tenacious) -}+and :: ShortcutFold Bool Bool+and = ShortcutFold+ { initial = Alive Tenacious ()+ , step = \_ a -> if a then Alive Tenacious () else Dead ()+ , extractLive = \() -> True+ , extractDead = \() -> False+ }++{-| 'True' if any input is 'True' (tenacious) -}+or :: ShortcutFold Bool Bool+or = ShortcutFold+ { initial = Alive Tenacious ()+ , step = \() a -> if a then Dead () else Alive Tenacious ()+ , extractLive = \() -> False+ , extractDead = \() -> True+ }++{-| 'True' if all inputs satisfy the predicate (tenacious) -}+all :: (a -> Bool) -> ShortcutFold a Bool+all predicate = ShortcutFold+ { initial = Alive Tenacious ()+ , step = \() a -> if predicate a then Alive Tenacious () else Dead ()+ , extractLive = \() -> True+ , extractDead = \() -> False+ }++{-| 'True' if any input satisfies the predicate (tenacious) -}+any :: (a -> Bool) -> ShortcutFold a Bool+any predicate = ShortcutFold+ { initial = Alive Tenacious ()+ , step = \_ a -> if predicate a then Dead () else Alive Tenacious ()+ , extractLive = \() -> False+ , extractDead = \() -> True+ }++{-| 'True' if any input is equal to the given value (tenacious) -}+element :: Eq a => a -> ShortcutFold a Bool+element a = any (a ==)++{-| 'False' if any input is equal to the given value (tenacious) -}+notElement :: Eq a => a -> ShortcutFold a Bool+notElement a = all (a /=)++{-| The first input that satisfies the predicate, if any (tenacious) -}+find :: (a -> Bool) -> ShortcutFold a (Maybe a)+find ok = ShortcutFold+ { initial = Alive Tenacious ()+ , step = \() a -> if ok a then Dead a else Alive Tenacious ()+ , extractDead = Just+ , extractLive = \() -> Nothing+ }++{-| The /n/th input, where n=0 is the first input, if the index is in+ bounds (tenacious) -}+index :: Natural -> ShortcutFold a (Maybe a)+index i = ShortcutFold+ { initial = Alive Tenacious i+ , step = \i' a -> if i' == 0 then Dead a else Alive Tenacious (i' - 1)+ , extractDead = Just+ , extractLive = \_ -> Nothing+ }++{-| The index of the first input that matches the given value, if any+ (tenacious) -}+elementIndex :: Eq a => a -> ShortcutFold a (Maybe Natural)+elementIndex a = findIndex (a ==)++{-| The index of the first input that satisfies the predicate, if any+ (tenacious) -}+findIndex :: (a -> Bool) -> ShortcutFold a (Maybe Natural)+findIndex ok = demotivate+ (+ liftA2 (,) (fold Fold.length) (find ok)+ <&> \(n, found) -> found $> (n - 1)+ )++{-| The @b@ from the first tuple where @a@ equals the given value,+ if any (tenacious) -}+lookup :: Eq a => a -> ShortcutFold (a, b) (Maybe b)+lookup a0 = ShortcutFold+ { initial = Alive Tenacious ()+ , step = \() (a, b) -> if a == a0 then Dead b else Alive Tenacious ()+ , extractLive = \() -> Nothing+ , extractDead = Just+ }
+ source/Fold/Shortcut/Run.hs view
@@ -0,0 +1,13 @@+module Fold.Shortcut.Run where++import Fold.Shortcut.Type++{-| Fold a listlike container to a single summary result, forcing+ only enough input to satisfy the short-cutting fold -}+run :: ShortcutFold a b -> [a] -> b+run ShortcutFold{ initial, step, extractDead, extractLive } = go initial+ where+ go (Alive Tenacious x) (a : as) = go (step x a) as+ go (Alive Tenacious x) [] = extractLive x+ go (Alive Ambivalent x) _ = extractLive x+ go (Dead x) _ = extractDead x
+ source/Fold/Shortcut/Type.hs view
@@ -0,0 +1,64 @@+module Fold.Shortcut.Type+ (+ ShortcutFold (..),+ Will (..), Vitality (..),+ )+ where++import Control.Applicative (Applicative, liftA2, pure, (<*>))+import Data.Functor (Functor, fmap)+import Data.Monoid (Monoid, mempty)+import Data.Semigroup (Semigroup, (<>))+import Strict (Will (..), Vitality (..))+import Data.Void (absurd)++import qualified Strict++{- | Processes inputs of type @a@, has the ability to halt midway+ through the stream, and results in a value of type @b@ -}+data ShortcutFold a b = forall x y. ShortcutFold+ { initial :: Vitality x y+ , step :: y -> a -> Vitality x y+ , extractDead :: x -> b+ , extractLive :: y -> b+ }++instance Functor (ShortcutFold a) where+ fmap f ShortcutFold{ step, initial, extractDead, extractLive } =+ ShortcutFold+ { initial+ , step+ , extractDead = \x -> f (extractDead x)+ , extractLive = \x -> f (extractLive x)+ }++instance Applicative (ShortcutFold a) where+ pure b = ShortcutFold+ { initial = Dead ()+ , step = absurd+ , extractDead = \() -> b+ , extractLive = absurd+ }++ (<*>)+ ShortcutFold{ initial = initialL, step = stepL, extractDead = extractDeadL, extractLive = extractLiveL }+ ShortcutFold{ initial = initialR, step = stepR, extractDead = extractDeadR, extractLive = extractLiveR } =+ ShortcutFold+ { initial = Strict.vitality2 initialL initialR+ , step = \(Strict.Tuple2 xL xR) a -> Strict.vitality2+ (Strict.unlessDead (\x -> stepL x a) xL)+ (Strict.unlessDead (\x -> stepR x a) xR)+ , extractDead = extract+ , extractLive = extract+ }+ where+ extract(Strict.Tuple2 xL xR) = f x+ where+ f = case xL of { Dead a -> extractDeadL a; Alive _ b -> extractLiveL b }+ x = case xR of { Dead a -> extractDeadR a; Alive _ b -> extractLiveR b }++instance Semigroup b => Semigroup (ShortcutFold a b) where+ (<>) = liftA2 (<>)++instance Monoid b => Monoid (ShortcutFold a b) where+ mempty = pure mempty
+ source/Fold/Shortcut/Utilities.hs view
@@ -0,0 +1,19 @@+module Fold.Shortcut.Utilities where++import Fold.Shortcut.Type++import Strict (willSave)++import qualified Strict++{-| Causes a shortcut fold to stop once it becomes ambivalent -}+demotivate :: ShortcutFold a b -> ShortcutFold a b+demotivate ShortcutFold{ initial, step, extractDead, extractLive } =+ ShortcutFold+ { initial = willSave initial+ , step = \x a -> willSave (step x a)+ , extractDead = \e -> case e of+ Strict.Left x -> extractDead x+ Strict.Right x -> extractLive x+ , extractLive = extractLive+ }
+ source/Fold/ShortcutNonempty.hs view
@@ -0,0 +1,28 @@+module Fold.ShortcutNonempty+ (+ {- * Type -} ShortcutNonemptyFold (..),++ {- * Run -} run,++ {- * Examples -}+ {- ** General -} magma, semigroup, monoid,+ {- ** Endpoints -} first, last,+ {- ** Extrema -} maximum, minimum, maximumBy, minimumBy,+ {- ** Length -} length,+ {- ** Boolean -} and, or, all, any,+ {- ** Numeric -} sum, product, mean, variance, standardDeviation,+ {- ** Search -} element, notElement, find, lookup,+ {- ** Index -} index, findIndex, elementIndex,+ {- ** List -} list, reverseList,++ {- * Conversion -} fold, effectfulFold, nonemptyFold, shortcutFold,++ {- * Utilities -} demotivate,+ )+ where++import Fold.ShortcutNonempty.Conversion+import Fold.ShortcutNonempty.Examples+import Fold.ShortcutNonempty.Run+import Fold.ShortcutNonempty.Type+import Fold.ShortcutNonempty.Utilities
+ source/Fold/ShortcutNonempty/Conversion.hs view
@@ -0,0 +1,51 @@+module Fold.ShortcutNonempty.Conversion where++import Fold.ShortcutNonempty.Type++import Data.Functor.Identity (Identity)+import Fold.Effectful.Type (EffectfulFold)+import Fold.Nonempty.Type (NonemptyFold)+import Fold.Pure.Type (Fold (Fold))+import Fold.Shortcut.Type (ShortcutFold (ShortcutFold))+import Fold.Nonempty.Type (NonemptyFold (NonemptyFold))+import Data.Void (absurd)++import qualified Fold.Pure.Conversion as Fold+import qualified Fold.Pure.Type as Fold+import qualified Fold.Shortcut.Type as Shortcut+import qualified Fold.Nonempty.Type as Nonempty++fold :: Fold a b -> ShortcutNonemptyFold a b+fold+ Fold{ Fold.initial, Fold.step, Fold.extract } =+ ShortcutNonemptyFold+ { initial = \a -> Alive Ambivalent (step initial a)+ , step = \x a -> Alive Ambivalent (step x a)+ , extractDead = absurd+ , extractLive = extract+ }++effectfulFold :: EffectfulFold Identity a b -> ShortcutNonemptyFold a b+effectfulFold x = fold (Fold.effectfulFold x)++nonemptyFold :: NonemptyFold a b -> ShortcutNonemptyFold a b+nonemptyFold+ NonemptyFold{ Nonempty.initial, Nonempty.step, Nonempty.extract } =+ ShortcutNonemptyFold+ { initial = \a -> Alive Ambivalent (initial a)+ , step = \x a -> Alive Ambivalent (step x a)+ , extractDead = absurd+ , extractLive = extract+ }++shortcutFold :: ShortcutFold a b -> ShortcutNonemptyFold a b+shortcutFold ShortcutFold{ Shortcut.initial, Shortcut.step,+ Shortcut.extractDead, Shortcut.extractLive } =+ ShortcutNonemptyFold+ { initial = case initial of+ Dead x -> \_ -> Dead x+ Alive _ x -> step x+ , step = step+ , extractDead = extractDead+ , extractLive = extractLive+ }
+ source/Fold/ShortcutNonempty/Examples.hs view
@@ -0,0 +1,16 @@+module Fold.ShortcutNonempty.Examples+ (+ {- * General -} magma, semigroup, monoid,+ {- * Endpoints -} first, last,+ {- * Extrema -} maximum, minimum, maximumBy, minimumBy,+ {- * Length -} length,+ {- * Boolean -} and, or, all, any,+ {- * Numeric -} sum, product, mean, variance, standardDeviation,+ {- * Search -} element, notElement, find, lookup,+ {- * Index -} index, findIndex, elementIndex,+ {- * List -} list, reverseList,+ )+ where++import Fold.ShortcutNonempty.Examples.Interesting+import Fold.ShortcutNonempty.Examples.Boring
+ source/Fold/ShortcutNonempty/Examples/Boring.hs view
@@ -0,0 +1,147 @@+-- | Folds of other types trivially lifted into 'ShortcutNonempty'+module Fold.ShortcutNonempty.Examples.Boring+ (+ {- * Search -} element, notElement, find, lookup,+ {- * Arithmetic folds -} sum, product, mean, variance, standardDeviation,+ {- * Working with indices -} index, findIndex, elementIndex,+ {- * Counting inputs -} length,+ {- * Boolean folds -} and, or, all, any,+ {- * Min/max -} maximum, minimum, maximumBy, minimumBy,+ {- * First/last -} last,+ {- * General folds -} magma, semigroup, monoid,+ {- * List folds -} list, reverseList,+ )+ where++import Data.Maybe (Maybe)+import Fold.ShortcutNonempty.Type (ShortcutNonemptyFold)+import Data.Semigroup (Semigroup)+import Data.Ord (Ord, Ordering)+import Data.Monoid (Monoid)+import Prelude (Floating, Fractional, Num)+import Data.Bool (Bool)+import Data.Eq (Eq)+import Numeric.Natural (Natural)++import qualified Fold.Shortcut.Examples.Interesting as Shortcut+import qualified Fold.Nonempty.Examples.Interesting as Nonempty+import qualified Fold.Pure.Examples.Interesting as Pure+import qualified Fold.ShortcutNonempty.Conversion as Convert++{-| Start with 'mempty', append each input on the right+ with '<>' (ambivalent) -}+monoid :: Monoid a => ShortcutNonemptyFold a a+monoid = Convert.fold Pure.monoid++{-| The number of inputs (ambivalent) -}+length :: ShortcutNonemptyFold a Natural+length = Convert.fold Pure.length++{-| 'True' if all inputs are 'True' (tenacious) -}+and :: ShortcutNonemptyFold Bool Bool+and = Convert.shortcutFold Shortcut.and++{-| 'True' if any input is 'True' (tenacious) -}+or :: ShortcutNonemptyFold Bool Bool+or = Convert.shortcutFold Shortcut.or++{-| 'True' if all inputs satisfy the predicate (tenacious) -}+all :: (a -> Bool) -> ShortcutNonemptyFold a Bool+all predicate = Convert.shortcutFold (Shortcut.all predicate)++{-| 'True' if any input satisfies the predicate (tenacious) -}+any :: (a -> Bool) -> ShortcutNonemptyFold a Bool+any predicate = Convert.shortcutFold (Shortcut.any predicate)++{-| Adds the inputs (ambivalent) -}+sum :: Num a => ShortcutNonemptyFold a a+sum = Convert.fold Pure.sum++{-| Multiplies the inputs (ambivalent) -}+product :: Num a => ShortcutNonemptyFold a a+product = Convert.fold Pure.product++{-| Numerically stable arithmetic mean of the inputs (ambivalent) -}+mean :: Fractional a => ShortcutNonemptyFold a a+mean = Convert.fold Pure.mean++{-| Numerically stable (population) variance over the+ inputs (ambivalent) -}+variance :: Fractional a => ShortcutNonemptyFold a a+variance = Convert.fold Pure.variance++{-| Numerically stable (population) standard deviation over+ the inputs (ambivalent) -}+standardDeviation :: Floating a => ShortcutNonemptyFold a a+standardDeviation = Convert.fold Pure.standardDeviation++{-| 'True' if any input is equal to the given value (tenacious) -}+element :: Eq a => a -> ShortcutNonemptyFold a Bool+element a = Convert.shortcutFold (Shortcut.element a)++{-| 'False' if any input is equal to the given value (tenacious) -}+notElement :: Eq a => a -> ShortcutNonemptyFold a Bool+notElement a = Convert.shortcutFold (Shortcut.notElement a)++{-| The first input that satisfies the predicate, if any (tenacious) -}+find :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe a)+find ok = Convert.shortcutFold (Shortcut.find ok)++{-| The /n/th input, where n=0 is the first input, if the index+ is in bounds (tenacious) -}+index :: Natural -> ShortcutNonemptyFold a (Maybe a)+index i = Convert.shortcutFold (Shortcut.index i)++{-| The index of the first input that matches the given value,+ if any (tenacious) -}+elementIndex :: Eq a => a -> ShortcutNonemptyFold a (Maybe Natural)+elementIndex a = Convert.shortcutFold (Shortcut.elementIndex a)++{-| The index of the first input that satisfies the predicate,+ if any (tenacious) -}+findIndex :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe Natural)+findIndex ok = Convert.shortcutFold (Shortcut.findIndex ok)++{-| The @b@ from the first tuple where @a@ equals the given value,+ if any (tenacious) -}+lookup :: Eq a => a -> ShortcutNonemptyFold (a, b) (Maybe b)+lookup a = Convert.shortcutFold (Shortcut.lookup a)++{-| All the inputs (ambivalent) -}+list :: ShortcutNonemptyFold a [a]+list = Convert.fold Pure.list++{-| All the inputs in reverse order (ambivalent) -}+reverseList :: ShortcutNonemptyFold a [a]+reverseList = Convert.fold Pure.reverseList++{-| Start with the first input, append each new input on the right+ with the given function (ambivalent) -}+magma :: (a -> a -> a) -> ShortcutNonemptyFold a a+magma step = Convert.nonemptyFold (Nonempty.magma step)++{-| Append each new input on the right with '<>' (ambivalent) -}+semigroup :: Semigroup a => ShortcutNonemptyFold a a+semigroup = Convert.nonemptyFold Nonempty.semigroup++{-| The last input (ambivalent) -}+last :: ShortcutNonemptyFold a a+last = Convert.nonemptyFold Nonempty.last++{-| The greatest input (ambivalent) -}+maximum :: Ord a => ShortcutNonemptyFold a a+maximum = Convert.nonemptyFold Nonempty.maximum++{-| The greatest input with respect to the given comparison+ function (ambivalent) -}+maximumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a+maximumBy cmp = Convert.nonemptyFold (Nonempty.maximumBy cmp)++{-| The least input (ambivalent) -}+minimum :: Ord a => ShortcutNonemptyFold a a+minimum = Convert.nonemptyFold Nonempty.minimum++{-| The least input with respect to the given comparison+ function (ambivalent) -}+minimumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a+minimumBy cmp = Convert.nonemptyFold (Nonempty.minimumBy cmp)
+ source/Fold/ShortcutNonempty/Examples/Interesting.hs view
@@ -0,0 +1,15 @@+module Fold.ShortcutNonempty.Examples.Interesting where++import Fold.ShortcutNonempty.Type++import Data.Function (id)+import Data.Void (absurd)++{-| The first input (tenacious) -}+first :: ShortcutNonemptyFold a a+first = ShortcutNonemptyFold+ { initial = Dead+ , step = absurd+ , extractDead = id+ , extractLive = absurd+ }
+ source/Fold/ShortcutNonempty/Run.hs view
@@ -0,0 +1,16 @@+module Fold.ShortcutNonempty.Run where++import Fold.ShortcutNonempty.Type++import Data.List.NonEmpty (NonEmpty ((:|)))++{-| Fold a nonempty listlike container to a single summary result,+ forcing only enough input to satisfy the short-cutting fold -}+run :: ShortcutNonemptyFold a b -> NonEmpty a -> b+run ShortcutNonemptyFold{ initial, step, extractDead, extractLive } =+ \(z :| as) -> go (initial z) as+ where+ go (Alive Tenacious x) (a : as) = go (step x a) as+ go (Alive Tenacious x) [] = extractLive x+ go (Alive Ambivalent x) _ = extractLive x+ go (Dead x) _ = extractDead x
+ source/Fold/ShortcutNonempty/Type.hs view
@@ -0,0 +1,64 @@+module Fold.ShortcutNonempty.Type+ (+ ShortcutNonemptyFold (..),+ Will (..), Vitality (..),+ )+ where++import Control.Applicative (Applicative, liftA2, pure, (<*>))+import Data.Functor (Functor, fmap)+import Data.Monoid (Monoid, mempty)+import Data.Semigroup (Semigroup, (<>))+import Strict (Will (..), Vitality (..))+import Data.Void (absurd)++import qualified Strict++{- | Processes at least one input of type @a@, has the ability to halt+ midway through the stream, and results in a value of type @b@ -}+data ShortcutNonemptyFold a b = forall x y. ShortcutNonemptyFold+ { initial :: a -> Vitality x y+ , step :: y -> a -> Vitality x y+ , extractDead :: x -> b+ , extractLive :: y -> b+ }++instance Functor (ShortcutNonemptyFold a) where+ fmap f ShortcutNonemptyFold{ step, initial, extractDead, extractLive } =+ ShortcutNonemptyFold+ { initial+ , step+ , extractDead = \x -> f (extractDead x)+ , extractLive = \x -> f (extractLive x)+ }++instance Applicative (ShortcutNonemptyFold a) where+ pure b = ShortcutNonemptyFold+ { initial = \_ -> Dead ()+ , step = absurd+ , extractDead = \() -> b+ , extractLive = absurd+ }++ (<*>)+ ShortcutNonemptyFold{ initial = initialL, step = stepL, extractDead = extractDeadL, extractLive = extractLiveL }+ ShortcutNonemptyFold{ initial = initialR, step = stepR, extractDead = extractDeadR, extractLive = extractLiveR } =+ ShortcutNonemptyFold+ { initial = \a -> Strict.vitality2 (initialL a) (initialR a)+ , step = \(Strict.Tuple2 xL xR) a -> Strict.vitality2+ (Strict.unlessDead (\x -> stepL x a) xL)+ (Strict.unlessDead (\x -> stepR x a) xR)+ , extractDead = extract+ , extractLive = extract+ }+ where+ extract(Strict.Tuple2 xL xR) = f x+ where+ f = case xL of { Dead a -> extractDeadL a; Alive _ b -> extractLiveL b }+ x = case xR of { Dead a -> extractDeadR a; Alive _ b -> extractLiveR b }++instance Semigroup b => Semigroup (ShortcutNonemptyFold a b) where+ (<>) = liftA2 (<>)++instance Monoid b => Monoid (ShortcutNonemptyFold a b) where+ mempty = pure mempty
+ source/Fold/ShortcutNonempty/Utilities.hs view
@@ -0,0 +1,19 @@+module Fold.ShortcutNonempty.Utilities where++import Fold.ShortcutNonempty.Type++import Strict (willSave)++import qualified Strict++{-| Causes a shortcut fold to stop once it becomes ambivalent -}+demotivate :: ShortcutNonemptyFold a b -> ShortcutNonemptyFold a b+demotivate ShortcutNonemptyFold{ initial, step, extractDead, extractLive } =+ ShortcutNonemptyFold+ { initial = \a -> willSave (initial a)+ , step = \x a -> willSave (step x a)+ , extractDead = \e -> case e of+ Strict.Left x -> extractDead x+ Strict.Right x -> extractLive x+ , extractLive = extractLive+ }
source/Fold/Types.hs view
@@ -1,3 +1,3 @@-module Fold.Types (Fold, NonemptyFold, EffectfulFold) where+module Fold.Types (Fold, NonemptyFold, EffectfulFold, ShortcutFold, ShortcutNonemptyFold) where import Fold
source/Strict.hs view
@@ -7,11 +7,14 @@ {- * Maybe -} Maybe (..), lazy, strict, {- * Either -} Either (..), hush, {- * Tuples -} Tuple2 (..), Tuple3 (..),+ {- * Shortcut -} Vitality (..), Will (..),+ unlessDead, vitality2, willSave, ) where -import Data.Semigroup (Semigroup, (<>))+import Data.Functor (Functor (..)) import Data.Monoid (Monoid, mempty)+import Data.Semigroup (Semigroup, (<>)) import qualified Data.Maybe as Lazy @@ -42,3 +45,34 @@ data Tuple2 a b = Tuple2 a b data Tuple3 a b c = Tuple3 a b c++data Will = Ambivalent | Tenacious++instance Semigroup Will where+ Tenacious <> _ = Tenacious+ _ <> Tenacious = Tenacious+ _ <> _ = Ambivalent++instance Monoid Will where+ mempty = Ambivalent++data Vitality a b = Dead a | Alive Will b+ deriving Functor++unlessDead :: (b -> Vitality a b) -> Vitality a b -> Vitality a b+unlessDead f s = case s of { Alive _ x -> f x; _ -> s }++willSave :: Vitality a b -> Vitality (Either a b) b+willSave v = case v of+ Dead x -> Dead (Left x)+ Alive Ambivalent x -> Dead (Right x)+ Alive Tenacious x -> Alive Tenacious x++type Vitality' a = Vitality a a++vitality2 :: Vitality a1 b1 -> Vitality a2 b2+ -> Vitality' (Strict.Tuple2 (Vitality a1 b1) (Vitality a2 b2))+vitality2 a@(Alive v1 _) b@(Alive v2 _) = Alive (v1 <> v2) (Strict.Tuple2 a b)+vitality2 a@(Dead _) b@(Alive v _) = Alive v (Strict.Tuple2 a b)+vitality2 a@(Alive v _) b@(Dead _) = Alive v (Strict.Tuple2 a b)+vitality2 a@(Dead _) b@(Dead _) = Dead (Strict.Tuple2 a b)
test/Main.hs view
@@ -7,9 +7,13 @@ import qualified Spec.Pure import qualified Spec.Nonempty import qualified Spec.Effectful+import qualified Spec.Shortcut+import qualified Spec.ShortcutNonempty main :: IO () main = hspec do Spec.Pure.spec Spec.Nonempty.spec Spec.Effectful.spec+ Spec.Shortcut.spec+ Spec.ShortcutNonempty.spec
test/Spec/Effectful.hs view
@@ -13,6 +13,7 @@ import Data.Monoid (mempty) import Data.Semigroup (Sum (Sum), (<>)) import Prelude ((>), String, Integer, (+), (*))+import Data.Bool (Bool (..)) import qualified Data.List as List @@ -83,3 +84,11 @@ shouldBe @(Identity Integer) (run (prefilter (Identity . p) f) xs) (run f (List.filter p xs))++ describe "null" do+ it "True for []" do+ run null ([] :: [Integer]) `shouldBe` Identity True+ it "False for anything else" do+ run null ([1] :: [Integer]) `shouldBe` Identity False+ run null ([1,2] :: [Integer]) `shouldBe` Identity False+ run null ([1,2,3] :: [Integer]) `shouldBe` Identity False
test/Spec/Pure.hs view
@@ -12,6 +12,7 @@ import Data.Monoid (mempty) import Data.Semigroup (Sum (Sum)) import Prelude ((>), String, Integer, (+), (*))+import Data.Bool (Bool (..)) import qualified Data.Foldable as Foldable import qualified Data.List as List@@ -116,3 +117,23 @@ describe "reverseList" do it "gets all inputs in reverse" do run reverseList xs `shouldBe` [4, 3, 2, 1]++ describe "endpoint functions" do+ describe "first" do+ it "gets the first item" do+ run first ([5, 4, 3] :: [Integer]) `shouldBe` Just 5+ it "returns Nothing with no input" do+ run first ([] :: [Integer]) `shouldBe` Nothing+ describe "last" do+ it "gets the last item" do+ run last ([5, 4, 3] :: [Integer]) `shouldBe` Just 3+ it "returns Nothing with no input" do+ run last ([] :: [Integer]) `shouldBe` Nothing++ describe "null" do+ it "True for []" do+ run null ([] :: [Integer]) `shouldBe` True+ it "False for anything else" do+ run null ([1] :: [Integer]) `shouldBe` False+ run null ([1,2] :: [Integer]) `shouldBe` False+ run null ([1,2,3] :: [Integer]) `shouldBe` False
+ test/Spec/Shortcut.hs view
@@ -0,0 +1,81 @@+module Spec.Shortcut where++import Fold.Shortcut++import Test.Hspec++import Control.Applicative (pure, (<$>), (<*>))+import Prelude (Integer, undefined)+import Data.Maybe (Maybe (Just, Nothing))+import Data.List ((++))+import Data.Bool (Bool (..))++import qualified Data.Char as Char++spec :: SpecWith ()+spec = describe "ShortcutFold" do++ it "Applicative" do+ let x = do+ a <- length+ b <- find Char.isLetter+ c <- elementIndex 'x'+ d <- elementIndex 'y'+ e <- last+ pure (a, b, c, d, e)+ run x ("1234xyz" ++ undefined) `shouldBe` (6, Just 'x', Just 4, Just 5, Just 'y')++ describe "first" do+ it "gets the first item" do+ shouldBe @(Maybe Integer) (run first [5, 4, 3]) (Just 5)+ it "is lazy" do+ shouldBe @(Maybe Integer) (run first (5 : undefined)) (Just 5)+ it "returns Nothing for []" do+ shouldBe @(Maybe Integer) (run first []) Nothing+ it "is tenacious" do+ shouldBe ((run ((,) <$> length <*> first)) "abc") (1, Just 'a')++ describe "endpoint functions" do+ describe "first" do+ it "gets the first item" do+ run first ([5, 4, 3] :: [Integer]) `shouldBe` Just 5+ it "returns Nothing with no input" do+ run first ([] :: [Integer]) `shouldBe` Nothing+ it "is lazy" do+ run first (5 : undefined :: [Integer]) `shouldBe` Just 5++ describe "null" do+ it "True for []" do+ run null ([] :: [Integer]) `shouldBe` True+ it "False for anything else" do+ run null ([1] :: [Integer]) `shouldBe` False+ run null ([1,2] :: [Integer]) `shouldBe` False+ run null ([1,2,3] :: [Integer]) `shouldBe` False++ describe "and" do+ it "True for []" do+ run and [] `shouldBe` True+ it "True for [True, ...]" do+ run and [True] `shouldBe` True+ run and [True,True] `shouldBe` True+ run and [True,True,True] `shouldBe` True+ it "False for anything else" do+ run and [False] `shouldBe` False+ run and [False,True] `shouldBe` False+ run and [True,False] `shouldBe` False+ it "is lazy" do+ run and (False : undefined) `shouldBe` False++ describe "or" do+ it "False for []" do+ run or [] `shouldBe` False+ it "False for [False, ...]" do+ run or [False] `shouldBe` False+ run or [False,False] `shouldBe` False+ run or [False,False,False] `shouldBe` False+ it "True for anything else" do+ run or [True] `shouldBe` True+ run or [False,True] `shouldBe` True+ run or [True,False] `shouldBe` True+ it "is lazy" do+ run or (True : undefined) `shouldBe` True
+ test/Spec/ShortcutNonempty.hs view
@@ -0,0 +1,59 @@+module Spec.ShortcutNonempty where++import Fold.ShortcutNonempty++import Test.Hspec++import Control.Applicative (pure, (<$>), (<*>))+import Prelude (Integer, undefined)+import Data.List.NonEmpty (NonEmpty ((:|)))+import Data.Maybe (Maybe (Just))+import Data.Bool (Bool (..))+import Data.List ((++))++import qualified Data.Char as Char++spec :: SpecWith ()+spec = describe "ShortcutNonemptyFold" do++ it "Applicative" do+ let x = do+ a <- length+ b <- find Char.isLetter+ c <- elementIndex 'x'+ d <- elementIndex 'y'+ e <- last+ pure (a, b, c, d, e)+ run x ('1' :| "234xyz" ++ undefined) `shouldBe` (6, Just 'x', Just 4, Just 5, 'y')++ describe "first" do+ it "gets the first item" do+ shouldBe @Integer (run first [5, 4, 3]) 5+ it "is lazy" do+ shouldBe @Integer (run first (5 :| undefined)) 5+ it "is tenacious" do+ shouldBe ((run ((,) <$> length <*> first)) ('a' :| "bc")) (1, 'a')++ describe "and" do+ it "True for [True, ...]" do+ run and [True] `shouldBe` True+ run and [True,True] `shouldBe` True+ run and [True,True,True] `shouldBe` True+ it "False for anything else" do+ run and [False] `shouldBe` False+ run and [False,True] `shouldBe` False+ run and [True,False] `shouldBe` False+ it "is lazy" do+ run and (False :| undefined) `shouldBe` False++ describe "or" do+ it "False for [False, ...]" do+ run or [False] `shouldBe` False+ run or [False,False] `shouldBe` False+ run or [False,False,False] `shouldBe` False+ it "True for anything else" do+ run or [True] `shouldBe` True+ run or [False,True] `shouldBe` True+ run or [True,False] `shouldBe` True+ it "is lazy" do+ run or (True :| undefined) `shouldBe` True