flow (empty) → 1.0.0
raw patch · 8 files changed
+391/−0 lines, 8 filesdep +QuickCheckdep +basedep +criterionsetup-changed
Dependencies added: QuickCheck, base, criterion, doctest, flow, template-haskell
Files
- Bench.hs +35/−0
- CHANGELOG.md +9/−0
- Flow.hs +191/−0
- LICENSE.md +21/−0
- README.md +77/−0
- Setup.hs +6/−0
- Test.hs +6/−0
- flow.cabal +46/−0
+ Bench.hs view
@@ -0,0 +1,35 @@+module Main (main) where++import Criterion.Main+import Flow++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+ ]+ , 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+ ]+ , 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+ ]+ ]++x :: Int+x = 1++f :: Int -> Int+f = (+ 2)++g :: Int -> Int+g = (* 3)
+ CHANGELOG.md view
@@ -0,0 +1,9 @@+# Change log++## v1.0.0 (2015-04-01)++- Initially released.++## v0.0.0 (2015-04-01)++- Initially created.
+ Flow.hs view
@@ -0,0 +1,191 @@+{- |+ Flow provides functions and operators for writing more understandable+ Haskell.++ Flow does not export anything that conflicts with the "Prelude". The+ recommended way to use Flow is to import it unqualified.++ >>> import Flow+-}+module Flow (+ -- * Function application+ apply, (|>), (<|),+ -- * Function composition+ compose, (.>), (<.),+ -- * Strict function application+ apply', (!>), (<!)+) where++import Prelude (seq)++{- $setup+ >>> import Prelude+ >>> let f = (+ 2)+ >>> let g = (* 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++ 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.++ >>> False |> not |> fromEnum+ 1++ This operator can be used with higher-order functions, but 'apply' might be+ clearer.++ >>> map (False |>) [not, id]+ [True,False]+-}+infixl 0 |>+(|>) :: a -> (a -> b) -> b+x |> f = apply x f++{- |+ prop> (f <| x) == 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.++ >>> fromEnum <| not <| False+ 1++ With higher-order functions, this operator is a clearer alternative to+ @flip 'apply'@.++ >>> map (<| False) [not, id]+ [True,False]+-}+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++ Composing many functions together quickly becomes unwieldy. Use '.>' or+ '<.' instead.++ >>> (not `compose` fromEnum `compose` succ) False+ 2+-}+compose :: (a -> b) -> (b -> c) -> (a -> c)+compose f g = \ x -> g (f x)++{- |+ prop> (f .> g) x == 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".++ >>> (not .> fromEnum) False+ 1++ Thanks to its high precedence, composing many functions together is easy.++ >>> (not .> fromEnum .> succ) False+ 2+-}+infixl 9 .>+(.>) :: (a -> b) -> (b -> c) -> (a -> c)+f .> g = compose f g++{- |+ prop> (g <. f) x == g (f x)++ Right-associative 'compose' operator. This is like the 'Prelude..'+ operator. Read it as "compose backward" or "but first".++ >>> (fromEnum <. not) False+ 1++ Composing many functions together is easy thanks to its high precedence.++ >>> (succ <. fromEnum <. not) False+ 2+-}+infixr 9 <.+(<.) :: (b -> c) -> (a -> b) -> (a -> c)+g <. f = compose f g++{- |+ prop> apply' x f == seq x (f x)++ Strict function application. This is like the 'Prelude.$!' operator.++ >>> apply' undefined (const False)+ *** Exception: Prelude.undefined+-}+apply' :: a -> (a -> b) -> b+apply' x f = seq x (apply x f)++{- |+ prop> (x !> f) == seq x (f x)++ Left-associative 'apply'' operator. This is like a flipped version of the+ 'Prelude.$!' operator.++ >>> undefined !> const False+ *** Exception: Prelude.undefined+-}+infixl 0 !>+(!>) :: a -> (a -> b) -> b+x !> f = apply' x f++{- |+ prop> (f <! x) == seq x (f x)++ Right-associative 'apply'' operator. This is like the 'Prelude.$!'+ operator.++ >>> const False <! undefined+ *** Exception: Prelude.undefined+-}+infixr 0 <!+(<!) :: (a -> b) -> a -> b+f <! x = apply' x f
+ LICENSE.md view
@@ -0,0 +1,21 @@+The MIT License (MIT)++Copyright (c) 2015 Taylor Fausak <taylor@fausak.me>++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ README.md view
@@ -0,0 +1,77 @@+<h1 align="center">+ <a href="https://github.com/tfausak/flow">+ Flow+ </a>+</h1>++<p align="center">+ Functions and operators for more understandable Haskell+</p>++<p align="center">+ <a href="https://hackage.haskell.org/package/flow"><img alt="" src="https://img.shields.io/hackage/v/flow.svg"></a>+ <a href="https://travis-ci.org/tfausak/flow"><img alt="" src="https://img.shields.io/travis/tfausak/flow/master.svg"></a>+ <a href="http://packdeps.haskellers.com/feed?needle=flow"><img alt="" src="https://img.shields.io/hackage-deps/v/flow.svg"></a>+</p>++<hr>++Flow provides functions and operators for writing more understandable Haskell.++- [Install](#install)+- [Use](#use)+- [Develop](#develop)++## Install++To use Flow in a Cabal package, add it to your Cabal file.++```+build-depends:+ flow ==1.*+```++For other use cases, install it with Cabal.++``` sh+$ cabal update+$ cabal install 'flow ==1.*'+```++Flow uses [Semantic Versioning][]. Check out [the change log][] for a+detailed list of changes.++## Use++Flow is designed to be imported unqualified. It does not export anything+that conflicts with the Prelude. To get started, simply import it.++``` hs+import Flow+```++Check out [the Haddock documentation][] for more information about the+functions Flow provides.++## Develop++If you want to help develop Flow, you'll need Git, GHC, and Cabal. To get+started, clone the repository and install the dependencies.++``` sh+$ git clone https://github.com/tfausak/flow+$ cd flow++$ cabal sandbox init+$ cabal install --enable-benchmarks --enable-tests --only-dependencies+```++Once you've done that, you should be able to use the normal Cabal tools+(`repl`, `test`, `haddock`, and `bench` in particular). If you've made changes+that you want merged into this repository, create a fork and open a pull+request. GitHub's [Fork A Repo][] article can help with that.++[semantic versioning]: http://semver.org/spec/v2.0.0.html+[the change log]: CHANGELOG.md+[the haddock documentation]: https://hackage.haskell.org/package/flow+[fork a repo]: https://help.github.com/articles/fork-a-repo/
+ Setup.hs view
@@ -0,0 +1,6 @@+module Main (main) where++import Distribution.Simple (defaultMain)++main :: IO ()+main = defaultMain
+ Test.hs view
@@ -0,0 +1,6 @@+module Main (main) where++import Test.DocTest (doctest)++main :: IO ()+main = doctest ["Flow.hs"]
+ flow.cabal view
@@ -0,0 +1,46 @@+name: flow+version: 1.0.0+cabal-version: >=1.8+build-type: Simple+license: MIT+license-file: LICENSE.md+maintainer: Taylor Fausak <taylor@fausak.me>+synopsis: Functions and operators for more understandable Haskell+description:+ Flow provides functions and operators for writing more understandable+ Haskell.+category: Utility+extra-source-files:+ CHANGELOG.md+ README.md++source-repository head+ type: git+ location: https://github.com/tfausak/flow++library+ exposed-modules:+ Flow+ build-depends:+ base <5+ ghc-options: -Wall++test-suite test+ type: exitcode-stdio-1.0+ main-is: Test.hs+ build-depends:+ base -any,+ flow -any,+ doctest ==0.9.*,+ QuickCheck ==2.*,+ template-haskell ==2.*+ ghc-options: -Wall -Werror++benchmark bench+ type: exitcode-stdio-1.0+ main-is: Bench.hs+ build-depends:+ base -any,+ flow -any,+ criterion ==1.*+ ghc-options: -Wall -Werror