control-block 0.0.0 → 0.0.1
raw patch · 4 files changed
+211/−58 lines, 4 filesdep +witherabledep −containersdep ~indexed-traversablePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: witherable
Dependencies removed: containers
Dependency ranges changed: indexed-traversable
API changes (from Hackage documentation)
+ Control.Block: (<$?>) :: Filterable f => (a -> Maybe b) -> f a -> f b
+ Control.Block: (<&?>) :: Filterable f => f a -> (a -> Maybe b) -> f b
+ Control.Block: (<**>) :: Applicative f => f a -> f (a -> b) -> f b
+ Control.Block: apply :: Applicative f => f (x -> y) -> f x -> f y
+ Control.Block: changeMaybe :: Filterable t => t x -> (x -> Maybe y) -> t y
+ Control.Block: emptn :: [x] -> y -> (NonEmpty x -> y) -> y
+ Control.Block: filter :: Filterable f => (a -> Bool) -> f a -> f a
+ Control.Block: filterA :: (Witherable t, Applicative f) => (a -> f Bool) -> t a -> f (t a)
+ Control.Block: foldMap1 :: (Foldable1 t, Semigroup m) => (a -> m) -> t a -> m
+ Control.Block: foldMapA :: (Foldable t, Applicative f, Monoid m) => (x -> f m) -> t x -> f m
+ Control.Block: foldMapA1 :: (Foldable1 t, Applicative f, Semigroup s) => (x -> f s) -> t x -> f s
+ Control.Block: forMaybe :: (Witherable t, Applicative f) => t a -> (a -> f (Maybe b)) -> f (t b)
+ Control.Block: ichangeMaybe :: FilterableWithIndex i t => t x -> (i -> x -> Maybe y) -> t y
+ Control.Block: ifilter :: FilterableWithIndex i t => (i -> a -> Bool) -> t a -> t a
+ Control.Block: ifilterA :: (WitherableWithIndex i t, Applicative f) => (i -> a -> f Bool) -> t a -> f (t a)
+ Control.Block: ifoldMapA :: (FoldableWithIndex i t, Applicative f, Monoid m) => (i -> x -> f m) -> t x -> f m
+ Control.Block: iforMaybe :: (Applicative f, WitherableWithIndex i t) => t x -> (i -> x -> f (Maybe y)) -> f (t y)
+ Control.Block: imapMaybe :: FilterableWithIndex i t => (i -> a -> Maybe b) -> t a -> t b
+ Control.Block: ireduceA :: (FoldableWithIndex i t, Applicative f, Monoid m) => t x -> (i -> x -> f m) -> f m
+ Control.Block: isift :: FilterableWithIndex i t => t x -> (i -> x -> Bool) -> t x
+ Control.Block: isiftA :: (Applicative f, WitherableWithIndex i t) => t x -> (i -> x -> f Bool) -> f (t x)
+ Control.Block: iwither :: (WitherableWithIndex i t, Applicative f) => (i -> a -> f (Maybe b)) -> t a -> f (t b)
+ Control.Block: mabye :: Maybe x -> y -> (x -> y) -> y
+ Control.Block: mapMaybe :: Filterable f => (a -> Maybe b) -> f a -> f b
+ Control.Block: reduce1 :: (Foldable1 t, Semigroup s) => t x -> (x -> s) -> s
+ Control.Block: reduceA :: (Foldable t, Applicative f, Monoid m) => t x -> (x -> f m) -> f m
+ Control.Block: reduceA1 :: (Foldable1 t, Applicative f, Semigroup s) => t x -> (x -> f s) -> f s
+ Control.Block: reduceL1 :: Foldable1 t => t x -> (x -> x -> x) -> x
+ Control.Block: reduceR1 :: Foldable1 t => t x -> (x -> x -> x) -> x
+ Control.Block: sift :: Filterable t => t x -> (x -> Bool) -> t x
+ Control.Block: siftA :: (Applicative f, Witherable t) => t x -> (x -> f Bool) -> f (t x)
+ Control.Block: through :: Applicative f => f x -> f (x -> y) -> f y
+ Control.Block: wither :: (Witherable t, Applicative f) => (a -> f (Maybe b)) -> t a -> f (t b)
- Control.Block: infixl 1 <&>
+ Control.Block: infixl 1 <&?>
- Control.Block: infixl 4 <$>
+ Control.Block: infixl 4 <$?>
Files
- CHANGELOG.md +4/−4
- LICENSE +1/−1
- control-block.cabal +10/−15
- lib/Control/Block.hs +196/−38
CHANGELOG.md view
@@ -1,6 +1,6 @@-# Revision history for blocks+# Revision history for `control-block` -## 0.0.0 -- 2023-04-11+## 0.0.1 -* Names for common higher-order functions where the function argument is final,- allowing easier use of `-XBlockArguments`.+Higher-order functions with their function arguments at the end,+for channeling the full power of BlockArguments and LambdaCase .
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2023, Melanie Phoenix+Copyright (c) 2024, Melanie Phoenix All rights reserved. Redistribution and use in source and binary forms, with or without
control-block.cabal view
@@ -1,38 +1,33 @@ cabal-version: 3.0 name: control-block-version: 0.0.0+version: 0.0.1 license: BSD-2-Clause license-file: LICENSE-author: Melanie Phoenix Brown+author: Melanie Phoenix maintainer: brown.m@proton.me category: Control build-type: Simple extra-doc-files: CHANGELOG.md synopsis:- Higher-order functions with their function arguments at the end+ Higher-order functions with their function arguments at the end,+ for channeling the full power of BlockArguments and LambdaCase . +description:+ Higher-order functions with their function arguments at the end,+ for channeling the full power of BlockArguments and LambdaCase .+ library ghc-options: -Wall hs-source-dirs: lib default-language: GHC2021 default-extensions: BlockArguments- DataKinds- DefaultSignatures- DerivingStrategies- FunctionalDependencies LambdaCase- MultiWayIf- OverloadedStrings PatternSynonyms- QuasiQuotes- RecordWildCards- TypeFamilies- ViewPatterns build-depends: , base >=4.14 && <5- , containers- , indexed-traversable+ , indexed-traversable >=0.1.3 && <0.2+ , witherable >=0.4.2 && <0.5 exposed-modules: Control.Block
lib/Control/Block.hs view
@@ -1,64 +1,222 @@-module Control.Block (- -- * Functor- (<$>),- (<&>),- fmap,- imap,- change,- ichange,+-- |+-- Higher-order functions with their function arguments at the end,+-- for channeling the full power of BlockArguments and LambdaCase .+module Control.Block+ ( -- * Functor+ (<$>)+ , (<&>)+ , fmap+ , imap+ , change+ , ichange - -- * Foldable- foldMap,- ifoldMap,- reduce,- reduceL,- reduceR,- ireduce,- ifor_,- itraverse_,+ -- * Applicative+ , (<**>)+ , apply+ , through - -- * Traversable- traverse,- itraverse,- for,- ifor,+ -- * Monad+ , bind+ , ibind - -- * Monad- bind,- ibind,-) where+ -- * Foldable -import Control.Monad (join)-import Data.Foldable (foldl')-import Data.Foldable.WithIndex (FoldableWithIndex (ifoldMap), ifor_, itraverse_)-import Data.Functor ((<&>))-import Data.Functor.WithIndex (FunctorWithIndex (imap))-import Data.Traversable (for)-import Data.Traversable.WithIndex (TraversableWithIndex (itraverse), ifor)+ -- ** With monoids+ , Fold.foldMap+ , foldMap1+ , foldMapA+ , foldMapA1+ , ifoldMap+ , ifoldMapA+ , reduce+ , reduce1+ , reduceA+ , reduceA1+ , ireduce+ , ireduceA + -- ** Without monoids+ , reduceL+ , reduceL1+ , reduceR+ , reduceR1++ -- * Traversable+ , traverse+ , itraverse+ , itraverse_+ , for+ , ifor+ , ifor_++ -- * Maybe and List+ , mabye+ , emptn++ -- * Filterable+ , (<$?>)+ , (<&?>)+ , filter+ , ifilter+ , sift+ , isift+ , Witherable.mapMaybe+ , imapMaybe+ , changeMaybe+ , ichangeMaybe++ -- * Witherable+ , filterA+ , ifilterA+ , siftA+ , isiftA+ , wither+ , iwither+ , forMaybe+ , iforMaybe+ )+where++import Control.Applicative+import Control.Monad+import Data.Foldable (Foldable)+import Data.Foldable qualified as Fold+import Data.Foldable.WithIndex+import Data.Foldable1 (Foldable1, foldMap1, foldl1', toNonEmpty)+import Data.Function+import Data.Functor+import Data.Functor.WithIndex+import Data.List.NonEmpty (NonEmpty ((:|)))+import Data.Maybe+import Data.Monoid (Monoid (mempty))+import Data.Semigroup+import Data.Traversable+import Data.Traversable.WithIndex+import Witherable+import Prelude (Bool)++-- | Non-infix version of '(<&>)'. change :: (Functor f) => f x -> (x -> y) -> f y change = (<&>) +-- | Flipped version of 'imap'. ichange :: (FunctorWithIndex i f) => f x -> (i -> x -> y) -> f y ichange = flip imap --- reduce1 :: (Foldable1 t, Semigroup s) => t x -> (x -> s) -> s--- reduce1 = flip foldMap1+-- | Non-infix version of '(<*>)'.+apply :: (Applicative f) => f (x -> y) -> f x -> f y+apply = (<*>) +-- | Flipped version of 'apply'. Non-infix version of '(<**>)'.+through :: (Applicative f) => f x -> f (x -> y) -> f y+through = (<**>)++-- | 'foldMap' through an 'Applicative' functor.+foldMapA :: (Foldable t, Applicative f, Monoid m) => (x -> f m) -> t x -> f m+foldMapA f = Fold.foldl' (\ !fm x -> liftA2 (<>) fm (f x)) (pure mempty)++-- | 'ifoldMap' through an 'Applicative' functor.+ifoldMapA ::+ (FoldableWithIndex i t, Applicative f, Monoid m) =>+ ((i -> x -> f m) -> t x -> f m)+ifoldMapA f = ifoldl' (\i !fm x -> liftA2 (<>) fm (f i x)) (pure mempty)++-- | 'foldMap1' through an 'Applicative' functor.+foldMapA1 ::+ (Foldable1 t, Applicative f, Semigroup s) => (x -> f s) -> t x -> f s+foldMapA1 f tx = case toNonEmpty tx of+ x :| [] -> f x+ x :| (y : ys) -> liftA2 (<>) (f x) (foldMapA1 f (y :| ys))++-- | Flipped version of 'foldMap1'.+reduce1 :: (Foldable1 t, Semigroup s) => t x -> (x -> s) -> s+reduce1 = flip foldMap1++-- | Flipped version of 'foldMap'. reduce :: (Foldable t, Monoid m) => t x -> (x -> m) -> m-reduce = flip foldMap+reduce = flip Fold.foldMap +-- | Flipped version of 'ifoldMap'. ireduce :: (FoldableWithIndex i t, Monoid m) => t x -> (i -> x -> m) -> m ireduce = flip ifoldMap +-- | A version of 'foldl'' taking the accumulator first, then the @Foldable@. reduceL :: (Foldable t) => y -> t x -> (y -> x -> y) -> y-reduceL = flip . flip foldl'+reduceL = flip . flip Fold.foldl' +-- | A version of 'foldl1'' taking the accumulator first, then the @Foldable1@.+reduceL1 :: (Foldable1 t) => t x -> (x -> x -> x) -> x+reduceL1 = flip foldl1'++-- | A version of 'foldr' taking the accumulator first, then the @Foldable@. reduceR :: (Foldable t) => y -> t x -> (x -> y -> y) -> y-reduceR = flip . flip foldr+reduceR = flip . flip Fold.foldr +-- | A version of 'foldr1' taking the accumulator first, then the @Foldable@.+reduceR1 :: (Foldable1 t) => t x -> (x -> x -> x) -> x+reduceR1 = flip Fold.foldr1++-- | Flipped version of 'foldMapA'.+reduceA :: (Foldable t, Applicative f, Monoid m) => t x -> (x -> f m) -> f m+reduceA = flip foldMapA++-- | Flipped version of 'foldMapA'.+ireduceA ::+ (FoldableWithIndex i t, Applicative f, Monoid m) =>+ t x ->+ (i -> x -> f m) ->+ f m+ireduceA = flip ifoldMapA++-- | Flipped version of 'foldMapA1'.+reduceA1 ::+ (Foldable1 t, Applicative f, Semigroup s) => t x -> (x -> f s) -> f s+reduceA1 = flip foldMapA1++-- | Non-infix version of '(>>=)'. bind :: (Monad f) => f x -> (x -> f y) -> f y bind = (>>=) +-- | Indexed version of 'bind'. ibind :: (FunctorWithIndex i f, Monad f) => f x -> (i -> x -> f y) -> f y ibind = (join .) . ichange++-- | A version of 'maybe' with the 'Maybe' argument first.+mabye :: Maybe x -> y -> (x -> y) -> y+mabye mx nothing just = maybe nothing just mx++-- | Act on the empty or 'NonEmpty' cases of a regular list.+emptn :: [x] -> y -> (NonEmpty x -> y) -> y+emptn lx y xy = case lx of [] -> y; (x : xs) -> xy (x :| xs)++-- | Flipped version of 'filter'.+sift :: (Filterable t) => t x -> (x -> Bool) -> t x+sift = flip filter++-- | Flipped version of 'ifilter'.+isift :: (FilterableWithIndex i t) => t x -> (i -> x -> Bool) -> t x+isift = flip ifilter++-- | Flipped version of 'mapMaybe'.+changeMaybe :: (Filterable t) => t x -> (x -> Maybe y) -> t y+changeMaybe = flip Witherable.mapMaybe++-- | Flipped version of 'imapMaybe'.+ichangeMaybe :: (FilterableWithIndex i t) => t x -> (i -> x -> Maybe y) -> t y+ichangeMaybe = flip imapMaybe++-- | Flipped version of 'filterA'.+siftA :: (Applicative f, Witherable t) => t x -> (x -> f Bool) -> f (t x)+siftA = flip filterA++-- | Flipped version of 'ifilterA'.+isiftA ::+ (Applicative f, WitherableWithIndex i t) =>+ (t x -> (i -> x -> f Bool) -> f (t x))+isiftA = flip ifilterA++-- | Flipped version of 'iwither'.+iforMaybe ::+ (Applicative f, WitherableWithIndex i t) =>+ (t x -> (i -> x -> f (Maybe y)) -> f (t y))+iforMaybe = flip iwither