packages feed

flow 1.0.1 → 1.0.2

raw patch · 5 files changed

+170/−151 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -2,6 +2,10 @@  Flow uses [Semantic Versioning][]. +## v1.0.2 (2015-10-04)++-   Updated documentation.+ ## v1.0.1 (2015-06-04)  -   Updated documentation.
Flow.hs view
@@ -1,81 +1,70 @@ {- |-    Flow is a package that provides functions and operators for writing more-    understandable Haskell. It's an alternative to some common idioms like-    @($)@ for function application and @(.)@ for function composition.+    Flow provides operators for writing more understandable Haskell. It is an+    alternative to some common idioms like ('Prelude.$') for function+    application and ('Prelude..') for function composition.      Flow is designed to be imported unqualified. It does not export anything-    that conflicts with-    <http://hackage.haskell.org/package/base the base package>.+    that conflicts with the base package.      >>> import Flow -    For more information about Flow, please visit-    <http://taylor.fausak.me/flow/ the official site>.+    == Rationale++    I think that Haskell can be hard to read. It has two operators for applying+    functions. Both are not really necessary and only serve to reduce+    parentheses. But they make code hard to read. People who do not already+    know Haskell have no chance of guessing what @foo $ bar@ or @baz & qux@+    mean.++    Those that do know Haskell are forced to read lines forwards and backwards+    at the same time, thanks to function composition. Even something simple,+    like finding the minimum element, bounces around: @f = head . sort@.++    I think we can do better. By using directional operators, we can allow+    readers to move their eye in only one direction, be that left-to-right or+    right-to-left. And by using idioms common in other programming languages,+    we can allow people who aren't familiar with Haskell to guess at the+    meaning.++    So instead of ('Prelude.$'), I propose ('<|'). It is a pipe, which anyone+    who has touched a Unix system should be familiar with. And it points in the+    direction it sends arguments along. Similarly, replace ('Prelude.&') with+    ('|>'). And for composition, ('<.') replaces ('Prelude..'). I would have+    preferred @<<@, but its counterpart @>>@ is taken by Haskell's syntax.+    So-called "backwards" composition is normally expressed with+    ('Control.Category.>>>'), which Flow provides as ('.>'). -} module Flow (     -- * Function application-    apply, (|>), (<|),+    (|>), (<|), apply,     -- * Function composition-    compose, (.>), (<.),+    (.>), (<.), compose,     -- * Strict function application-    apply', (!>), (<!),+    (!>), (<!), apply', ) where  import Prelude (seq)  {- $setup     >>> import Prelude-    >>> let f = (+ 2)-    >>> let g = (* 2)-    >>> let h = (^ 2)+    >>> let f = (+ 3)+    >>> let g = (* 3)+    >>> let h = (^ 3) -}  {- |-    prop> apply x f == f x--    <https://en.wikipedia.org/wiki/Function_application Function application>.-    This is like the 'Prelude.$' operator.--    >>> apply False not-    True--    Using this function with many arguments is cumbersome. Use '|>' or '<|'-    instead.--    >>> False `apply` not `apply` fromEnum-    1--    This function usually isn't necessary since @'apply' x f@ is the same as-    @f x@. However it can come in handy when working with higher-order-    functions.--    >>> map (apply False) [not, id]-    [True,False]--}-apply :: a -> (a -> b) -> b-apply x f = f x--{- |     prop> (x |> f) == f x-    prop> (x |> f |> g) == g (f x) -    Left-associative 'apply' operator. This is like a flipped version of the-    'Prelude.$' operator. Read it as "apply forward" or "pipe into".--    >>> False |> not-    True--    Since this operator has such low precedence, it can be used to remove-    parentheses from complicated expressions.+    prop> (x |> f |> g) == g (f x) -    >>> False |> not |> fromEnum-    1+    Left-associative 'apply' operator. Read as "apply forward" or "pipe into".+    Use this to create long chains of computation that suggest which direction+    things move in. -    This operator can be used with higher-order functions, but 'apply' might be-    clearer.+    >>> 3 |> succ |> recip |> negate+    -0.25 -    >>> map (False |>) [not, id]-    [True,False]+    Or use it anywhere you would use ('Prelude.&'). -} infixl 0 |> (|>) :: a -> (a -> b) -> b@@ -83,62 +72,50 @@  {- |     prop> (f <| x) == f x-    prop> (g <| f <| x) == g (f x) -    Right-associative 'apply' operator. This is like the 'Prelude.$' operator.-    Read it as "apply backward" or "pipe from".--    >>> not <| False-    True--    This operator can be used to remove parentheses from complicated-    expressions because of its low precedence.+    prop> (g <| f <| x) == g (f x) -    >>> fromEnum <| not <| False-    1+    Right-associative 'apply' operator. Read as "apply backward" or "pipe+    from". Use this to create long chains of computation that suggest which+    direction things move in. You may prefer this operator over ('|>') for+    'Prelude.IO' actions since it puts the last function first. -    With higher-order functions, this operator is a clearer alternative to-    @flip 'apply'@.+    >>> print <| negate <| recip <| succ <| 3+    -0.25 -    >>> map (<| False) [not, id]-    [True,False]+    Or use it anywhere you would use ('Prelude.$'). -} infixr 0 <| (<|) :: (a -> b) -> a -> b f <| x = apply x f  {- |-    prop> compose f g x == g (f x)--    <https://en.wikipedia.org/wiki/Function_composition Function composition>.-    This is like the 'Prelude..' operator.--    >>> (compose not fromEnum) False-    1+    prop> apply x f == f x -    Composing many functions together quickly becomes unwieldy. Use '.>' or-    '<.' instead.+    Function application. This function usually isn't necessary, but it can be+    more readable than some alternatives when used with higher-order functions+    like 'Prelude.map'. -    >>> (not `compose` fromEnum `compose` succ) False-    2+    >>> map (apply 2) [succ, recip, negate]+    [3.0,0.5,-2.0] -}-compose :: (a -> b) -> (b -> c) -> (a -> c)-compose f g = \ x -> g (f x)+apply :: a -> (a -> b) -> b+apply x f = f x  {- |     prop> (f .> g) x == g (f x)-    prop> (f .> g .> h) x == h (g (f x)) -    Left-associative 'compose' operator. This is like a flipped version of the-    'Prelude..' operator. Read it as "compose forward" or "and then".+    prop> (f .> g .> h) x == h (g (f x)) -    >>> (not .> fromEnum) False-    1+    Left-associative 'compose' operator. Read as "compose forward" or "and+    then". Use this to create long chains of computation that suggest which+    direction things move in. -    Thanks to its high precedence, composing many functions together is easy.+    >>> let f = succ .> recip .> negate+    >>> f 3+    -0.25 -    >>> (not .> fromEnum .> succ) False-    2+    Or use it anywhere you would use ('Control.Category.>>>'). -} infixl 9 .> (.>) :: (a -> b) -> (b -> c) -> (a -> c)@@ -146,42 +123,56 @@  {- |     prop> (g <. f) x == g (f x)-    prop> (h <. g <. f) x == h (g (f x)) -    Right-associative 'compose' operator. This is like the 'Prelude..'-    operator. Read it as "compose backward" or "but first".+    prop> (h <. g <. f) x == h (g (f x)) -    >>> (fromEnum <. not) False-    1+    Right-associative 'compose' operator. Read as "compose backward" or "but+    first". Use this to create long chains of computation that suggest which+    direction things move in. You may prefer this operator over ('.>') for+    'Prelude.IO' actions since it puts the last function first. -    Composing many functions together is easy thanks to its high precedence.+    >>> let f = print <. negate <. recip <. succ+    >>> f 3+    -0.25 -    >>> (succ <. fromEnum <. not) False-    2+    Or use it anywhere you would use ('Prelude..'). -} infixr 9 <. (<.) :: (b -> c) -> (a -> b) -> (a -> c) g <. f = compose f g  {- |-    prop> apply' x f == seq x (f x)+    prop> compose f g x == g (f x) -    Strict function application. This is like the 'Prelude.$!' operator.+    Function composition. This function usually isn't necessary, but it can be+    more readable than some alternatives when used with higher-order functions+    like 'Prelude.map'. -    >>> apply' undefined (const False)-    *** Exception: Prelude.undefined+    >>> let fs = map (compose succ) [recip, negate]+    >>> map (apply 3) fs+    [0.25,-4.0] -}-apply' :: a -> (a -> b) -> b-apply' x f = seq x (apply x f)+compose :: (a -> b) -> (b -> c) -> (a -> c)+compose f g = \ x -> g (f x)  {- |     prop> (x !> f) == seq x (f x)-    prop> (x !> f !> g) == seq x (g (seq x (f x))) -    Left-associative 'apply'' operator. This is like a flipped version of the-    'Prelude.$!' operator.+    prop> (x !> f !> g) == let y = seq x (f x) in seq y (g y) -    >>> undefined !> const False+    Left-associative 'apply'' operator. Read as "strict apply forward" or+    "strict pipe info". Use this to create long chains of computation that+    suggest which direction things move in.++    >>> 3 !> succ !> recip !> negate+    -0.25++    The difference between this and ('|>') is that this evaluates its argument+    before passing it to the function.++    >>> undefined |> const True+    True+    >>> undefined !> const True     *** Exception: Prelude.undefined -} infixl 0 !>@@ -190,14 +181,46 @@  {- |     prop> (f <! x) == seq x (f x)-    prop> (g <! f <! x) == seq x (g (seq x (f x))) -    Right-associative 'apply'' operator. This is like the 'Prelude.$!'-    operator.+    prop> (g <! f <! x) == let y = seq x (f x) in seq y (g y) -    >>> const False <! undefined+    Right-associative 'apply'' operator. Read as "strict apply backward" or+    "strict pipe from". Use this to create long chains of computation that+    suggest which direction things move in. You may prefer this operator over+    ('!>') for 'Prelude.IO' actions since it puts the last function first.++    >>> print <! negate <! recip <! succ <! 3+    -0.25++    The difference between this and ('<|') is that this evaluates its argument+    before passing it to the function.++    >>> const True <| undefined+    True+    >>> const True <! undefined     *** Exception: Prelude.undefined -} infixr 0 <! (<!) :: (a -> b) -> a -> b f <! x = apply' x f++{- |+    prop> apply' x f == seq x (f x)++    Strict function application. This function usually isn't necessary, but it+    can be more readable than some alternatives when used with higher-order+    functions like 'Prelude.map'.++    >>> map (apply' 2) [succ, recip, negate]+    [3.0,0.5,-2.0]++    The different between this and 'apply' is that this evaluates its argument+    before passing it to the function.++    >>> apply undefined (const True)+    True+    >>> apply' undefined (const True)+    *** Exception: Prelude.undefined+-}+apply' :: a -> (a -> b) -> b+apply' x f = seq x (apply x f)
FlowBench.hs view
@@ -6,30 +6,30 @@ main :: IO () main = defaultMain     [ bgroup "application"-        [ bench "f x" $ whnf f x-        , bench "apply x f" $ whnf (apply x) f-        , bench "x |> f" $ whnf (x |>) f-        , bench "f <| x" $ whnf (<| x) f+        [ bench "f x" (whnf f x)+        , bench "apply x f" (whnf (apply x) f)+        , bench "x |> f" (whnf (x |>) f)+        , bench "f <| x" (whnf (<| x) f)         ]     , bgroup "composition"-        [ bench "f . g" $ whnf (f .) g-        , bench "compose f g" $ whnf (compose f) g-        , bench "f .> g" $ whnf (f .>) g-        , bench "g <. f" $ whnf (<. f) g+        [ bench "f . g" (whnf (f .) g)+        , bench "compose f g" (whnf (compose f) g)+        , bench "f .> g" (whnf (f .>) g)+        , bench "g <. f" (whnf (<. f) g)         ]     , bgroup "strict application"-        [ bench "seq x (f x)" $ whnf (seq x) (f x)-        , bench "apply' x f" $ whnf (apply' x) f-        , bench "x !> f" $ whnf (x !>) f-        , bench "f <! x" $ whnf (<! x) f+        [ bench "seq x (f x)" (whnf (seq x) (f x))+        , bench "apply' x f" (whnf (apply' x) f)+        , bench "x !> f" (whnf (x !>) f)+        , bench "f <! x" (whnf (<! x) f)         ]     ]  x :: Int-x = 2+x = 3  f :: Int -> Int-f = (+ 2)+f y = y + 3  g :: Int -> Int-g = (* 2)+g y = y * 3
README.md view
@@ -9,12 +9,13 @@ ---  Flow is a package that provides functions and operators for writing more-understandable Haskell. It's an alternative to some common idioms like+understandable Haskell. It is an alternative to some common idioms like [`($)`][] for function application and [`(.)`][] for function composition.  -   [Requirements](#requirements) -   [Installation](#installation) -   [Usage](#usage)+    -   [Cheat sheet](#cheat-sheet)  ## Requirements @@ -30,14 +31,7 @@ build-depends: flow ==1.0.* ``` -For other use cases, install it with Cabal.--``` sh-$ cabal install 'flow ==1.0.*'-```--Flow uses [Semantic Versioning][]. See [the change log][] for a detailed list-of changes.+See [the change log][] for a detailed list of changes.  ## Usage @@ -48,29 +42,28 @@ import Flow ``` -Here is a quick overview of the functions and operators that Flow provides.+### Cheat sheet  Flow            | Base --------------- | --------------`apply x f`     | `f x` `x |> f`        | `x & f` `f <| x`        | `f $ x`-`compose f g x` | `g (f x)`+`apply x f`     | `f x` `f .> g`        | `f >>> g` `g <. f`        | `g . f`-`apply' x f`    | `seq x (f x)`+`compose f g x` | `g (f x)` `x !> f`        | - `f <! x`        | `f $! x`+`apply' x f`    | `seq x (f x)`  For more information about Flow, please read [the Haddock documentation][].  [flow]: http://taylor.fausak.me/flow/-[version]: https://img.shields.io/hackage/v/flow.svg?label=version&style=flat-square-[build]: https://img.shields.io/travis/tfausak/flow/master.svg?label=build&style=flat-square-[dependencies]: https://img.shields.io/hackage-deps/v/flow.svg?label=dependencies&style=flat-square+[version]: https://img.shields.io/hackage/v/flow.svg?label=version+[build]: https://img.shields.io/travis/tfausak/flow/master.svg?label=build+[dependencies]: https://img.shields.io/hackage-deps/v/flow.svg?label=dependencies [`($)`]: http://hackage.haskell.org/package/base-4.8.0.0/docs/Prelude.html#v:-36- [`(.)`]: http://hackage.haskell.org/package/base-4.8.0.0/docs/Prelude.html#v:.-[semantic versioning]: http://semver.org/spec/v2.0.0.html [the change log]: CHANGELOG.md [the base package]: http://hackage.haskell.org/package/base [the haddock documentation]: https://hackage.haskell.org/package/flow/docs/Flow.html
flow.cabal view
@@ -1,5 +1,5 @@ name: flow-version: 1.0.1+version: 1.0.2 cabal-version: >=1.8 build-type: Simple license: MIT@@ -10,12 +10,9 @@ bug-reports: https://github.com/tfausak/flow/issues synopsis: Write more understandable Haskell. description:-    Flow is a package that provides functions and operators for writing more-    understandable Haskell. It's an alternative to some common idioms like-    @($)@ for function application and @(.)@ for function composition.-    .-    For more information, please visit-    <http://taylor.fausak.me/flow/ the official site>.+    Flow provides operators for writing more understandable Haskell. It is an+    alternative to some common idioms like (@$@) for function application and+    (@.@) for function composition. category: Combinators, Functions, Utility author: Taylor Fausak <taylor@fausak.me> extra-source-files:@@ -39,7 +36,7 @@     build-depends:         base -any,         flow -any,-        doctest >= 0.9 && <0.11,+        doctest >=0.9 && <0.11,         QuickCheck ==2.*,         template-haskell ==2.*     ghc-options: -Wall@@ -51,4 +48,6 @@         base -any,         flow -any,         criterion ==1.*+    other-modules:+        Flow     ghc-options: -Wall