packages feed

between 0.9.0.2 → 0.10.0.0

raw patch · 7 files changed

+1191/−540 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Function.Between: (<^@@^) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (f c -> d) -> a -> f b -> e
- Data.Function.Between: (<^@@^>) :: (Functor f, Functor g) => (a -> b -> c) -> (a -> d -> e) -> (f c -> g d) -> a -> f b -> g e
- Data.Function.Between: (<^@^) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (c -> f d) -> a -> b -> f e
- Data.Function.Between: (<^@^>) :: (Functor f, Functor g) => (a -> d -> e) -> (a -> b -> c) -> (f c -> g d) -> a -> f b -> g e
- Data.Function.Between: (<^@~) :: Functor f => (a -> c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
- Data.Function.Between: (<~@@~) :: Functor f => (a -> b) -> (c -> d) -> (f b -> c) -> f a -> d
- Data.Function.Between: (<~@@~>) :: (Functor f, Functor g) => (a -> b) -> (c -> d) -> (f b -> g c) -> f a -> g d
- Data.Function.Between: (<~@~) :: Functor f => (c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
- Data.Function.Between: (<~@~>) :: (Functor f, Functor g) => (c -> d) -> (a -> b) -> (f b -> g c) -> f a -> g d
- Data.Function.Between: (^@@^) :: (a -> b -> c) -> (a -> d -> e) -> (c -> d) -> a -> b -> e
- Data.Function.Between: (^@@^>) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (c -> f d) -> a -> b -> f e
- Data.Function.Between: (^@^) :: (a -> d -> e) -> (a -> b -> c) -> (c -> d) -> a -> b -> e
- Data.Function.Between: (^@^>) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (f c -> d) -> a -> f b -> e
- Data.Function.Between: (^@~) :: (a -> c -> d) -> (a -> b) -> (b -> c) -> a -> d
- Data.Function.Between: (~@@^) :: (a -> b) -> (a -> c -> d) -> (b -> c) -> a -> d
- Data.Function.Between: (~@@^>) :: Functor f => (a -> b) -> (a -> c -> d) -> (b -> f c) -> a -> f d
- Data.Function.Between: (~@@~) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d
- Data.Function.Between: (~@@~>) :: Functor f => (a -> b) -> (c -> d) -> (b -> f c) -> a -> f d
- Data.Function.Between: (~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
- Data.Function.Between: (~@~>) :: Functor f => (c -> d) -> (a -> b) -> (f b -> c) -> f a -> d
- Data.Function.Between: between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
- Data.Function.Between: between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d
- Data.Function.Between: between3l :: (c -> d) -> (a -> b) -> (b -> b -> b -> c) -> a -> a -> a -> d
+ Data.Function.Between.Lazy: (<^@@^) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (f c -> d) -> a -> f b -> e
+ Data.Function.Between.Lazy: (<^@@^>) :: (Functor f, Functor g) => (a -> b -> c) -> (a -> d -> e) -> (f c -> g d) -> a -> f b -> g e
+ Data.Function.Between.Lazy: (<^@^) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (c -> f d) -> a -> b -> f e
+ Data.Function.Between.Lazy: (<^@^>) :: (Functor f, Functor g) => (a -> d -> e) -> (a -> b -> c) -> (f c -> g d) -> a -> f b -> g e
+ Data.Function.Between.Lazy: (<^@~) :: Functor f => (a -> c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
+ Data.Function.Between.Lazy: (<~@@~) :: Functor f => (a -> b) -> (c -> d) -> (f b -> c) -> f a -> d
+ Data.Function.Between.Lazy: (<~@@~>) :: (Functor f, Functor g) => (a -> b) -> (c -> d) -> (f b -> g c) -> f a -> g d
+ Data.Function.Between.Lazy: (<~@~) :: Functor f => (c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
+ Data.Function.Between.Lazy: (<~@~>) :: (Functor f, Functor g) => (c -> d) -> (a -> b) -> (f b -> g c) -> f a -> g d
+ Data.Function.Between.Lazy: (^@@^) :: (a -> b -> c) -> (a -> d -> e) -> (c -> d) -> a -> b -> e
+ Data.Function.Between.Lazy: (^@@^>) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (c -> f d) -> a -> b -> f e
+ Data.Function.Between.Lazy: (^@^) :: (a -> d -> e) -> (a -> b -> c) -> (c -> d) -> a -> b -> e
+ Data.Function.Between.Lazy: (^@^>) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (f c -> d) -> a -> f b -> e
+ Data.Function.Between.Lazy: (^@~) :: (a -> c -> d) -> (a -> b) -> (b -> c) -> a -> d
+ Data.Function.Between.Lazy: (~@@^) :: (a -> b) -> (a -> c -> d) -> (b -> c) -> a -> d
+ Data.Function.Between.Lazy: (~@@^>) :: Functor f => (a -> b) -> (a -> c -> d) -> (b -> f c) -> a -> f d
+ Data.Function.Between.Lazy: (~@@~) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d
+ Data.Function.Between.Lazy: (~@@~>) :: Functor f => (a -> b) -> (c -> d) -> (b -> f c) -> a -> f d
+ Data.Function.Between.Lazy: (~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
+ Data.Function.Between.Lazy: (~@~>) :: Functor f => (c -> d) -> (a -> b) -> (f b -> c) -> f a -> d
+ Data.Function.Between.Lazy: between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
+ Data.Function.Between.Lazy: between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d
+ Data.Function.Between.Lazy: between3l :: (c -> d) -> (a -> b) -> (b -> b -> b -> c) -> a -> a -> a -> d
+ Data.Function.Between.Strict: (<^@@^) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (f c -> d) -> a -> f b -> e
+ Data.Function.Between.Strict: (<^@@^>) :: (Functor f, Functor g) => (a -> b -> c) -> (a -> d -> e) -> (f c -> g d) -> a -> f b -> g e
+ Data.Function.Between.Strict: (<^@^) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (c -> f d) -> a -> b -> f e
+ Data.Function.Between.Strict: (<^@^>) :: (Functor f, Functor g) => (a -> d -> e) -> (a -> b -> c) -> (f c -> g d) -> a -> f b -> g e
+ Data.Function.Between.Strict: (<^@~) :: Functor f => (a -> c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
+ Data.Function.Between.Strict: (<~@@~) :: Functor f => (a -> b) -> (c -> d) -> (f b -> c) -> f a -> d
+ Data.Function.Between.Strict: (<~@@~>) :: (Functor f, Functor g) => (a -> b) -> (c -> d) -> (f b -> g c) -> f a -> g d
+ Data.Function.Between.Strict: (<~@~) :: Functor f => (c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
+ Data.Function.Between.Strict: (<~@~>) :: (Functor f, Functor g) => (c -> d) -> (a -> b) -> (f b -> g c) -> f a -> g d
+ Data.Function.Between.Strict: (^@@^) :: (a -> b -> c) -> (a -> d -> e) -> (c -> d) -> a -> b -> e
+ Data.Function.Between.Strict: (^@@^>) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (c -> f d) -> a -> b -> f e
+ Data.Function.Between.Strict: (^@^) :: (a -> d -> e) -> (a -> b -> c) -> (c -> d) -> a -> b -> e
+ Data.Function.Between.Strict: (^@^>) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (f c -> d) -> a -> f b -> e
+ Data.Function.Between.Strict: (^@~) :: (a -> c -> d) -> (a -> b) -> (b -> c) -> a -> d
+ Data.Function.Between.Strict: (~@@^) :: (a -> b) -> (a -> c -> d) -> (b -> c) -> a -> d
+ Data.Function.Between.Strict: (~@@^>) :: Functor f => (a -> b) -> (a -> c -> d) -> (b -> f c) -> a -> f d
+ Data.Function.Between.Strict: (~@@~) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d
+ Data.Function.Between.Strict: (~@@~>) :: Functor f => (a -> b) -> (c -> d) -> (b -> f c) -> a -> f d
+ Data.Function.Between.Strict: (~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
+ Data.Function.Between.Strict: (~@~>) :: Functor f => (c -> d) -> (a -> b) -> (f b -> c) -> f a -> d
+ Data.Function.Between.Strict: between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
+ Data.Function.Between.Strict: between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d
+ Data.Function.Between.Strict: between3l :: (c -> d) -> (a -> b) -> (b -> b -> b -> c) -> a -> a -> a -> d

Files

ChangeLog.md view
@@ -1,5 +1,16 @@ # ChangeLog / ReleaseNotes ++## Version 0.10.0.0++* Original implementation moved to module `Data.Function.Between.Lazy` and is+  now reexported by `Data.Function.Between`. (new)+* Implementation of strict variants of all functions defined in+  `Data.Function.Between.Lazy` module. These new functions use+  `(f . g) x = f '$!' g '$!' x` as definition for function composition where+  `$!` is strict application. (new)++ ## Version 0.9.0.2  * Minor documentation changes.@@ -21,6 +32,7 @@ * First public release. * Uploaded to [Hackage][]:   <http://hackage.haskell.org/package/between-0.9.0.0>+   [Hackage]:
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2013, 2014, Peter Trško+Copyright (c) 2013-2015, Peter Trško  All rights reserved. 
README.md view
@@ -1,15 +1,21 @@ Between ======= -[![Hackage](https://budueba.com/hackage/between)][Hackage: between]+[![Hackage](http://img.shields.io/hackage/v/between.svg)][Hackage: between]+[![Haskell Programming Language](https://img.shields.io/badge/language-Haskell-blue.svg)][Haskell.org]+[![BSD3 License](http://img.shields.io/badge/license-BSD3-brightgreen.svg)][tl;dr Legal: BSD3] +[![Build](https://travis-ci.org/trskop/between.svg)](https://travis-ci.org/trskop/between) + Description -----------  It turns out that this combinator -    f ~@~ g = (f .) . (. g)+````Haskell+f ~@~ g = (f .) . (. g)+````  is a powerful thing. It was abstracted from following (commonly used) pattern `f . h . g` where `f` and `g` are fixed.@@ -20,13 +26,17 @@  Function `Data.Function.on` can be implemented using `~@~` as: -    on :: (b -> b -> c) -> (a -> b) -> a -> a -> c-    on f g = (id ~@~ g ~@~ g) f+````Haskell+on :: (b -> b -> c) -> (a -> b) -> a -> a -> c+on f g = (id ~@~ g ~@~ g) f+````  If function @on3@ existed in /base/ then it could be defined as: -    on3 :: (b -> b -> b -> d) -> (a -> b) -> a -> a -> a -> d-    on3 f g = (id ~@~ g ~@~ g ~@~ g) f+````Haskell+on3 :: (b -> b -> b -> d) -> (a -> b) -> a -> a -> a -> d+on3 f g = (id ~@~ g ~@~ g ~@~ g) f+````  For more examples see documentation. @@ -38,6 +48,14 @@ [Hackage][Hackage: between].  +Building Options+----------------++* `-fpedantic` (disabled by default)++  Pass additional warning flags to GHC.++ Contributions ------------- @@ -46,7 +64,14 @@ that).  + [Hackage: between]:     https://hackage.haskell.org/package/between [Hackage: lens]:     http://hackage.haskell.org/package/lens+[Haskell.org]:+  http://www.haskell.org+  "The Haskell Programming Language"+[tl;dr Legal: BSD3]:+  https://tldrlegal.com/license/bsd-3-clause-license-%28revised%29+  "BSD 3-Clause License (Revised)"
between.cabal view
@@ -1,5 +1,5 @@ name:                   between-version:                0.9.0.2+version:                0.10.0.0 synopsis:               Function combinator "between" and derived combinators description:   It turns out that this combinator@@ -25,7 +25,7 @@   > on3 f g = (id ~@~ g ~@~ g ~@~ g) f   .   Other usage examples and documentation can be found in-  "Data.Function.Between".+  "Data.Function.Between" module.  homepage:               https://github.com/trskop/between bug-reports:            https://github.com/trskop/between/issues@@ -33,7 +33,7 @@ license-file:           LICENSE author:                 Peter Trško maintainer:             peter.trsko@gmail.com-copyright:              (c) 2013, 2014 Peter Trško+copyright:              (c) 2013-2015 Peter Trško category:               Data build-type:             Simple cabal-version:          >=1.8@@ -43,20 +43,25 @@   , ChangeLog.md  flag pedantic-  description:-    Pass additional warning flags including -Werror to GHC during compilation.-  default: False+  description:          Pass additional warning flags to GHC.+  default:              False+  manual:               True  library   hs-source-dirs:       src-  exposed-modules:      Data.Function.Between+  exposed-modules:+      Data.Function.Between+    , Data.Function.Between.Lazy+    , Data.Function.Between.Strict   build-depends:        base > 3 && < 5    ghc-options:          -Wall-  if impl(ghc >= 6.8)-    ghc-options:        -fwarn-tabs   if flag(pedantic)-    ghc-options:        -Werror+    ghc-options:+      -fwarn-tabs+      -fwarn-implicit-prelude+      -fwarn-missing-import-lists+--    -Werror  source-repository head   type:                 git@@ -65,4 +70,4 @@ source-repository this   type:                 git   location:             git://github.com/trskop/between.git-  tag:                  v0.9.0.2+  tag:                  v0.10.0.0
src/Data/Function/Between.hs view
@@ -1,43 +1,53 @@ {-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -fno-warn-missing-import-lists #-} -- | -- Module:       $HEADER$ -- Description:  Function combinator "between" and its variations.--- Copyright:    (c) 2013, 2014 Peter Trsko+-- Copyright:    (c) 2013-2015 Peter Trsko -- License:      BSD3 -- -- Maintainer:   peter.trsko@gmail.com -- Stability:    experimental--- Portability:  portable+-- Portability:  NoImplicitPrelude -- -- During development it is common occurrence to modify deeply nested -- structures. One of the best known libraries for this purpose is -- <http://hackage.haskell.org/package/lens lens>, but it's quite -- overkill for some purposes. ----- This module describes simple and composable combinators that are built on+-- This library describes simple and composable combinators that are built on -- top of very basic concept: ----- @f '.' h '.' g@+-- @f . h . g@ -- -- Where @f@ and @g@ are fixed. It is possible to reduce it to just: ----- @(f '.') '.' ('.' g)@+-- @(f .) . (. g)@ -- -- Which is the core pattern used by all functions defined in this module. ----- Trying to generalize this pattern further ends as:+-- Trying to generalize this pattern further ends as -- @(f 'Data.Functor.<$>') '.' ('Data.Functor.<$>' g)@, where--- @'Data.Functor.<$>' = 'fmap'@. Other combinations of substituting '.' for--- 'fmap' will end up less or equally generic. Type of such expression is:+-- @'Data.Functor.<$>' = 'Data.Functor.fmap'@. Other combinations of+-- substituting 'Data.Function..' for 'Data.Functor.fmap' will end up less or+-- equally generic. Type of such expression is: ----- > \f g -> (f <$>) . (<$> g)--- >     :: Functor f => (b -> c) -> f a -> (a -> b) -> f c+-- @+-- \\f g -> (f 'Data.Functor.<$>') 'Data.Function..' ('Data.Functor.<$>' g)+--     :: 'Data.Functor.Functor' f => (b -> c) -> f a -> (a -> b) -> f c+-- @ -- -- Which doesn't give us much more power. Instead of going for such--- generalization we kept the original @((f '.') '.' ('.' g))@ which we named+-- generalization we kept the original @((f .) . (. g))@ which we named -- 'between' or '~@~' in its infix form. module Data.Function.Between     (+    -- | This module reexports "Data.Function.Between.Lazy" that uses standard+    -- definition of ('Data.Function..') function as a basis of all+    -- combinators. There is also module "Data.Function.Between.Strict", that+    -- uses strict definition of function composition.+      module Data.Function.Between.Lazy+     -- * Composability     --     -- $composability@@ -50,475 +60,108 @@     --     -- $lenses -    -- * Between Function Combinator+    -- * Related Work     ---    -- | Captures common pattern of @\\g -> (f '.' g '.' h)@ where @f@ and @h@-    -- are fixed parameters.-      between-    , (~@~)-    , (~@@~)+    -- | There are other packages out there that provide similar combinators. -    -- * Derived Combinators+    -- ** Package profunctors     ---    -- | Combinators that either further parametrise @f@ or @g@ in-    -- @f '.' g '.' h@, or apply '~@~' more then once.-    , (^@~)-    , (~@@^)--    , (^@^)-    , (^@@^)--    , between2l-    , between3l+    -- $profunctors -    -- ** Lifted Combinators+    -- ** Package pointless-fun     ---    -- | Combinators based on '~@~', '^@~', '^@^', and their flipped variants,-    -- that use 'fmap' to lift one or more of its arguments to operate in-    -- 'Functor' context.-    , (<~@~>)-    , (<~@@~>)--    , (<~@~)-    , (~@@~>)--    , (~@~>)-    , (<~@@~)--    , (<^@~)-    , (~@@^>)--    , (<^@^>)-    , (<^@@^>)--    , (<^@^)-    , (^@@^>)--    , (^@^>)-    , (<^@@^)+    -- $pointless-fun     )   where -import Data.Functor (Functor(fmap))-import Data.Function ((.), flip)+import Data.Function.Between.Lazy  --- | Core combinator of this module and we build others on top of. It also has--- an infix form '~@~' and flipped infix form '~@@~'.------ This function Defined as:------ @--- 'between' f g -> (f .) . (. g)--- @-between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d-between f g = (f .) . (. g)---- | Infix variant of 'between'.------ Fixity is left associative and set to value 8, which is one less then fixity--- of function composition ('.').-(~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d-(~@~) = between-infixl 8 ~@~---- | Flipped variant of '~@~', i.e. flipped infix variant of 'between'.------ Fixity is right associative and set to value 8, which is one less then--- fixity of function composition ('.').-(~@@~) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d-(~@@~) = flip between-infixr 8 ~@@~---- | As '~@~', but first function is also parametrised with @a@, hence the name--- '^@~'. Character @^@ indicates which argument is parametrised with--- additional argument.------ This function is defined as:------ @--- (f '^@~' g) h a -> (f a '~@~' g) h a--- @------ Fixity is left associative and set to value 8, which is one less then--- fixity of function composition ('.').-(^@~) :: (a -> c -> d) -> (a -> b) -> (b -> c) -> a -> d-(f ^@~ g) h a = (f a `between` g) h a-infixl 8 ^@~---- | Flipped variant of '^@~'.------ Fixity is right associative and set to value 8, which is one less then--- fixity of function composition ('.').-(~@@^) :: (a -> b) -> (a -> c -> d) -> (b -> c) -> a -> d-(~@@^) = flip (^@~)-infixr 8 ~@@^---- | Pass additional argument to first two function arguments.------ This function is defined as:------ @--- (f '^@^' g) h a b -> (f a '~@~' g a) h b--- @------ See also '^@~' to note the difference, most importantly that '^@~' passes--- the same argument to all its functional arguments. Function '^@~' can be--- defined in terms of this one as:------ @--- (f '^@~' g) h a = (f '^@^' 'Data.Function.const' g) h a a--- @------ We can do it also the other way around and define '^@^' using '^@~':------ @--- f '^@^' g =---     'Data.Tuple.curry' . (f . 'Data.Tuple.snd' '^@~' 'Data.Tuple.uncurry' g)--- @------ Fixity is set to value 8, which is one less then of function composition--- ('.').-(^@^) :: (a -> d -> e) -> (a -> b -> c) -> (c -> d) -> a -> b -> e-(f ^@^ g) h a = (f a `between` g a) h-infix 8 ^@^---- | Flipped variant of '^@^'.------ Fixity is set to value 8, which is one less then of function composition--- ('.').-(^@@^) :: (a -> b -> c) -> (a -> d -> e) -> (c -> d) -> a -> b -> e-(^@@^) = flip (^@^)-infix 8 ^@@^---- | Apply function @g@ to each argument of binary function and @f@ to its--- result. In suffix \"2l\" the number is equal to arity of the function it--- accepts as a third argument and character \"l\" is for \"left associative\".------ @--- 'between2l' f g = (f '~@~' g) '~@~' g--- @------ Interesting observation:------ @--- (\\f g -> 'between2l' 'Data.Function.id' g f) === 'Data.Function.on'--- @-between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d-between2l f g = (f `between` g) `between` g---- | Apply function @g@ to each argument of ternary function and @f@ to its--- result. In suffix \"3l\" the number is equal to arity of the function it--- accepts as a third argument and character \"l\" is for \"left associative\".------ This function is defined as:------ @--- 'between3l' f g = ((f '~@~' g) '~@~' g) '~@~' g--- @------ Alternatively it can be defined using 'between2l':------ @--- 'between3l' f g = 'between2l' f g '~@~' g--- @-between3l :: (c -> d) -> (a -> b) -> (b -> b -> b -> c) -> a -> a -> a -> d-between3l f g = ((f `between` g) `between` g) `between` g---- | Convenience wrapper for:------ @--- \\f g -> 'fmap' f '~@~' 'fmap' g--- @------ Name of '<~@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- both its arguments and then we apply '~@~'.------ Fixity is left associative and set to value 8, which is one less then--- of function composition ('.').-(<~@~>)-    :: (Functor f, Functor g)-    => (c -> d) -> (a -> b) -> (f b -> g c) -> f a -> g d-f <~@~> g = fmap f `between` fmap g-infix 8 <~@~>---- | Flipped variant of '<~@~>'.------ Name of '<~@@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- both its arguments and then we apply '~@@~'.------ Fixity is set to value 8, which is one less then of function composition--- ('.').-(<~@@~>)-    :: (Functor f, Functor g)-    => (a -> b) -> (c -> d) -> (f b -> g c) -> f a -> g d-f <~@@~> g = fmap g `between` fmap f-infix 8 <~@@~>---- | Apply fmap to first argument of '~@~'. Dual to '~@~>' which applies--- 'fmap' to second argument.------ Defined as:------ @--- f '<~@~' g = 'fmap' f '~@~' g--- @------ This function allows us to define lenses mostly for pair of functions that--- form an isomorphism. See section <#g:3 Constructing Lenses> for details.------ Name of '<~@~' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- first (left) argument and then we apply '~@~'.------ Fixity is left associative and set to value 8, which is one less then--- of function composition ('.').-(<~@~) :: Functor f => (c -> d) -> (a -> b) -> (b -> f c) -> a -> f d-(<~@~) = between . fmap-infixl 8 <~@~---- | Flipped variant of '<~@~'.------ This function allows us to define lenses mostly for pair of functions that--- form an isomorphism. See section <#g:3 Constructing Lenses> for details.------ Name of '~@@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- second (right) argument and then we apply '~@@~'.------ Fixity is right associative and set to value 8, which is one less then--- fixity of function composition ('.').-(~@@~>) :: Functor f => (a -> b) -> (c -> d) -> (b -> f c) -> a -> f d-(~@@~>) = flip (<~@~)-infixr 8 ~@@~>---- | Apply fmap to second argument of '~@~'. Dual to '<~@~' which applies--- 'fmap' to first argument.------ Defined as:------ @--- f '~@~>' g -> f '~@~' 'fmap' g--- @------ Name of '~@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- second (right) argument and then we apply '~@~'.------ Fixity is right associative and set to value 8, which is one less then--- of function composition ('.').-(~@~>) :: Functor f => (c -> d) -> (a -> b) -> (f b -> c) -> f a -> d-(~@~>) f = between f . fmap-infixl 8 ~@~>---- | Flipped variant of '~@~>'.------ Name of '<~@@~' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- first (left) argument and then we apply '~@@~'.------ Fixity is left associative and set to value 8, which is one less then--- fixity of function composition ('.').-(<~@@~) :: Functor f => (a -> b) -> (c -> d) -> (f b -> c) -> f a -> d-(<~@@~) = flip (~@~>)-infixr 8 <~@@~---- | Convenience wrapper for: @\\f g -> 'fmap' . f '^@~' g@.------ This function has the same functionality as function------ @--- lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b--- @------ Which is defined in <http://hackage.haskell.org/package/lens lens package>.--- Only difference is that arguments of '<^@~' are flipped. See also section--- <#g:3 Constructing Lenses>.------ Name of '<^@~' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- first (left) arguments and then we apply '^@~'.------ Fixity is left associative and set to value 8, which is one less then--- of function composition ('.').-(<^@~)-    :: Functor f-    => (a -> c -> d) -> (a -> b) -> (b -> f c) -> a -> f d-(<^@~) f = (fmap . f ^@~)-infixl 8 <^@~---- | Flipped variant of '~@^>'.------ This function has the same functionality as function+-- $composability -- -- @--- lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b+-- (f . h) '~@~' (i . g) === (f '~@~' g) . (h '~@~' i) -- @ ----- Which is defined in <http://hackage.haskell.org/package/lens lens package>.--- See also section <#g:3 Constructing Lenses>.------ Name of '~@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- second (right) arguments and then we apply '~@^>'.------ Fixity is left associative and set to value 8, which is one less then--- of function composition ('.').-(~@@^>)-    :: Functor f-    => (a -> b) -> (a -> c -> d) -> (b -> f c) -> a -> f d-(~@@^>) = flip (<^@~)-infixl 8 ~@@^>---- | Convenience wrapper for: @\\f g -> 'fmap' . f '^@^' 'fmap' . g@.------ Name of '<^@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- both its arguments and then we apply '^@^'.------ Fixity is left associative and set to value 8, which is one less then--- of function composition ('.').-(<^@^>)-    :: (Functor f, Functor g)-    => (a -> d -> e) -> (a -> b -> c) -> (f c -> g d) -> a -> f b -> g e-(f <^@^> g) h a = (fmap (f a) `between` fmap (g a)) h-infix 8 <^@^>---- | Flipped variant of '<^@^>'.------ Name of '<^@@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- both its arguments and then we apply '^@@^'.------ Fixity is set to value 8, which is one less then of function composition--- ('.').-(<^@@^>)-    :: (Functor f, Functor g)-    => (a -> b -> c) -> (a -> d -> e) -> (f c -> g d) -> a -> f b -> g e-(<^@@^>) = flip (<^@^>)-infix 8 <^@@^>---- | Convenience wrapper for: @\\f g -> 'fmap' . f '^@^' g@.------ This function allows us to define generic lenses from gettern and setter.--- See section <#g:3 Constructing Lenses> for details.------ Name of '<^@^' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- first (left) arguments and then we apply '^@^'.------ Fixity is left associative and set to value 8, which is one less then--- of function composition ('.').-(<^@^)-    :: Functor f-    => (a -> d -> e) -> (a -> b -> c) -> (c -> f d) -> a -> b -> f e-(f <^@^ g) h a = (fmap (f a) `between` g a) h-infix 8 <^@^---- | Flipped variant of '<^@^'.------ This function allows us to define generic lenses from gettern and setter.--- See section <#g:3 Constructing Lenses> for details.------ Name of '^@@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- second (right) arguments and then we apply '^@@^'.------ Fixity is set to value 8, which is one less then of function composition--- ('.').-(^@@^>)-    :: Functor f-    => (a -> b -> c) -> (a -> d -> e) -> (c -> f d) -> a -> b -> f e-(^@@^>) = flip (<^@^)-infix 8 ^@@^>---- | Convenience wrapper for: @\\f g -> f '^@^' 'fmap' . g@.------ Name of '^@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- second (right) arguments and then we apply '^@^'.------ Fixity is left associative and set to value 8, which is one less then--- of function composition ('.').-(^@^>)-    :: Functor f-    => (a -> d -> e) -> (a -> b -> c) -> (f c -> d) -> a -> f b -> e-(f ^@^> g) h a = (f a `between` fmap (g a)) h-infix 8 ^@^>---- | Flipped variant of '<^@^>'.------ Name of '<^@@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to--- first (left) arguments and then we apply '^@@^'.------ Fixity is set to value 8, which is one less then of function composition--- ('.').-(<^@@^)-    :: Functor f-    => (a -> b -> c) -> (a -> d -> e) -> (f c -> d) -> a -> f b -> e-(<^@@^) = flip (^@^>)-infix 8 <^@@^---- $composability------ > (f . h) ~@~ (i . g) === (f ~@~ g) . (h ~@~ i)------ This shows us that it is possible to define @(f '~@~' g)@ and @(h '~@~' i)@+-- This shows us that it is possible to define @(f ~\@~ g)@ and @(h ~\@~ i)@ -- separately, for reusability, and then compose them. -- -- The fun doesn't end on functions that take just one parameter, because '~@~' -- lets you build up things like: ----- > (f ~@~ funOnY) ~@~ funOnX--- >     === \g x y -> f (g (funOnX x) (funOnY y))+-- @+-- (f '~@~' funOnY) '~@~' funOnX+--     === \g x y -> f (g (funOnX x) (funOnY y))+-- @ -- -- As you can se above @g@ is a function that takes two parameters. Now we can--- define @(f '~@~' funOnY)@ separately, then when ever we need we can extend--- it to higher arity function by appending @('~@~' funOnX)@. Special case when+-- define @(f ~\@~ funOnY)@ separately, then when ever we need we can extend+-- it to higher arity function by appending @(~\@~ funOnX)@. Special case when -- @funOnY = funOnX@ is very interesting, in example function -- 'Data.Function.on' can be defined using 'between' as: ----- > on :: (b -> b -> c) -> (a -> b) -> a -> a -> c--- > on f g = (id ~@~ g ~@~ g) f--- >     -- or: ((. g) ~@~ g) f+-- @+-- on :: (b -> b -> c) -> (a -> b) -> a -> a -> c+-- on f g = ('Data.Function.id' '~@~' g '~@~' g) f+--     -- or: ((. g) ~@~ g) f+-- @ -- -- We can also define function @on3@ that takes function with arity three as -- its first argument: ----- > on3 :: (b -> b -> b -> d) -> (a -> b) -> a -> a -> a -> d--- > on3 f g = (id ~@~ g ~@~ g ~@~ g) f--- >     -- or: ((. g) ~@~ g ~@~ g) f+-- @+-- on3 :: (b -> b -> b -> d) -> (a -> b) -> a -> a -> a -> d+-- on3 f g = ('Data.Function.id' '~@~' g '~@~' g '~@~' g) f+--     -- or: ((. g) '~@~' g '~@~' g) f+-- @ -- -- If we once again consider generalizing above examples by using three -- different functions @g1 =\/= g2 =\/= g3@ instead of just one @g@ then we -- get: ----- > on' :: (b -> b1 -> c)--- >     -> (a2 -> b2)--- >     -> (a1 -> b1)--- >     -> a1 -> a2 -> c--- > on' f g1 g2 = (id ~@~ g2 ~@~ g1) f--- >--- > on3'--- >     :: (b1 -> b2 -> b3 -> c)--- >     -> (a3 -> b3)--- >     -> (a2 -> b2)--- >     -> (a1 -> b1)--- >     -> a1 -> a2 -> a3 -> c--- > on3' f g1 g2 g3 = (id ~@~ g3 ~@~ g2 ~@~ g1) f+-- @+-- on' :: (b -> b1 -> c)+--     -> (a2 -> b2)+--     -> (a1 -> b1)+--     -> a1 -> a2 -> c+-- on' f g1 g2 = ('Data.Function.id' '~@~' g2 '~@~' g1) f --+-- on3'+--     :: (b1 -> b2 -> b3 -> c)+--     -> (a3 -> b3)+--     -> (a2 -> b2)+--     -> (a1 -> b1)+--     -> a1 -> a2 -> a3 -> c+-- on3' f g1 g2 g3 = ('Data.Function.id' '~@~' g3 '~@~' g2 '~@~' g1) f+-- @+-- -- Which allows us to interpret '~@~' in terms like \"apply this function to -- the n-th argument before passing it to the function @f@\". We just have to -- count the arguments backwards. In example if want to apply function @g@ to -- third argument, but no other then we can use: ----- > \g f -> (id ~@~ g ~@~ id ~@~ id) f--- >     --   ^      ^     ^      ^- Applied to the first argument.--- >     --   |      |     '- Applied to the second argument.--- >     --   |      '- Applied to the third argument.--- >     --   '- Applied to the result.--- >     :: (a3 -> b3) -> (a1 -> a2 -> b3 -> c) -> a1 -> a2 -> a3 -> c+-- @+-- \\g f -> ('Data.Function.id' '~@~' g '~@~' 'Data.Function.id' '~@~' 'Data.Function.id') f+--     --   ^      ^     ^      ^- Applied to the first argument.+--     --   |      |     '- Applied to the second argument.+--     --   |      '- Applied to the third argument.+--     --   '- Applied to the result.+--     :: (a3 -> b3) -> (a1 -> a2 -> b3 -> c) -> a1 -> a2 -> a3 -> c+-- @ -- -- Or we can use '~@@~', which is just flipped version of '~@~' and then it -- would be: ----- > \g f -> (id ~@@~ id ~@@~ g ~@@~ id) f--- >     --   ^       ^       ^      ^- Applied to the result.--- >     --   |       |       '- Applied to the third argument.--- >     --   |       '- Applied to the second argument.--- >     --   '- Applied to the first argument.--- >     :: (a3 -> b3) -> (a1 -> a2 -> b3 -> c) -> a1 -> a2 -> a3 -> c+-- @+-- \\g f -> ('Data.Function.id' '~@@~' 'Data.Function.id' '~@@~' g '~@@~' 'Data.Function.id') f+--     --   ^       ^       ^      ^- Applied to the result.+--     --   |       |       '- Applied to the third argument.+--     --   |       '- Applied to the second argument.+--     --   '- Applied to the first argument.+--     :: (a3 -> b3) -> (a1 -> a2 -> b3 -> c) -> a1 -> a2 -> a3 -> c+-- @ ----- Another interesting situation is when @f@ and @g@ in @(f '~@~' g)@ form an+-- Another interesting situation is when @f@ and @g@ in @(f ~\@~ g)@ form an -- isomorphism. Then we can construct a mapping function that takes function -- operating on one type and transform it in to a function that operates on a -- different type. As we shown before it is also possible to map functions with@@ -530,51 +173,57 @@  -- $mappingFunctionsForNewtypes ----- When we use @(f '~@~' g)@ where @f@ and @g@ form an isomorphism of two+-- When we use @(f ~\@~ g)@ where @f@ and @g@ form an isomorphism of two -- types, and if @f@ is a constructor and @g@ a selector of newtype, then--- @(f '~@~' g)@ is a mapping function that allows us to manipulate value+-- @(f ~\@~ g)@ is a mapping function that allows us to manipulate value -- wrapped inside a newtype. ----- > newtype T t a = T {fromT :: a}--- >--- > mapT--- >     :: (a -> b)--- >     -> T t a -> T t' b--- > mapT = T ~@~ fromT+-- @+-- newtype T t a = T {fromT :: a} ----- Note that @mapT@ above is generalized version of 'fmap' of obvious 'Functor'--- instance for newtype @T@.+-- mapT+--     :: (a -> b)+--     -> T t a -> T t' b+-- mapT = T '~@~' fromT+-- @ --+-- Note that @mapT@ above is generalized version of 'Data.Functor.fmap' of+-- obvious 'Data.Functor.Functor' instance for newtype @T@.+-- -- Interestingly, we can use 'between' to define higher order mapping functions -- by simple chaining: ----- > mapT2--- >     :: (a -> b -> c)--- >     -> T t1 a -> T t2 b -> T t3 c--- > mapT2 = mapT ~@~ fromT--- >     -- or: T ~@~ fromT ~@~ fromT--- >     -- or: mapT `between2l` fromT--- >--- > mapT3--- >     :: (a -> b -> c -> d)--- >     -> T t1 a -> T t2 b -> T t3 c -> T t4 d--- > mapT3 = mapT2 ~@~ fromT--- >     -- or: T ~@~ fromT ~@~ fromT ~@~ fromT--- >     -- or: mapT `between3l` fromT+-- @+-- mapT2+--     :: (a -> b -> c)+--     -> T t1 a -> T t2 b -> T t3 c+-- mapT2 = mapT '~@~' fromT+--     -- or: T '~@~' fromT '~@~' fromT+--     -- or: mapT `between2l` fromT --+-- mapT3+--     :: (a -> b -> c -> d)+--     -> T t1 a -> T t2 b -> T t3 c -> T t4 d+-- mapT3 = mapT2 '~@~' fromT+--     -- or: T '~@~' fromT '~@~' fromT '~@~' fromT+--     -- or: mapT `between3l` fromT+-- @+-- -- Dually to definition of 'mapT' and 'mapT2' we can also define: ----- > comapT :: (T a -> T b) -> a -> b--- > comapT = fromT ~@~ T--- >     -- or: T ~@@~ fromT--- >--- > comapT2 :: (T a -> T b -> T c) -> a -> b -> c--- > comapT2 = fromT ~@~ T ~@~ T--- >     -- or: comapT ~@~ T--- >     -- or: T ~@@~ T ~@@~ fromT--- >     -- or: T ~@@~ comapT--- >     -- or: fromT `between2l` T+-- @+-- comapT :: (T a -> T b) -> a -> b+-- comapT = fromT '~@~' T+--     -- or: T '~@@~' fromT --+-- comapT2 :: (T a -> T b -> T c) -> a -> b -> c+-- comapT2 = fromT '~@~' T '~@~' T+--     -- or: comapT '~@~' T+--     -- or: T '~@@~' T '~@@~' fromT+--     -- or: T '~@@~' comapT+--     -- or: fromT `between2l` T+-- @+-- -- In code above we can read code like: -- -- @@@ -593,31 +242,35 @@ -- Here is another example with a little more complex type wrapped inside a -- newtype: ----- > newtype T e a = T {fromT :: Either e a}--- >--- > mapT--- >     :: (Either e a -> Either e' b)--- >     -> T e a -> T e' b--- > mapT = T ~@~ fromT--- >--- > mapT2--- >     :: (Either e1 a -> Either e2 b -> Either e3 c)--- >     -> T e1 a -> T e2 b -> T e3 c--- > mapT2 = mapT ~@~ fromT+-- @+-- newtype T e a = T {fromT :: Either e a} --+-- mapT+--     :: (Either e a -> Either e' b)+--     -> T e a -> T e' b+-- mapT = T '~@~' fromT+--+-- mapT2+--     :: (Either e1 a -> Either e2 b -> Either e3 c)+--     -> T e1 a -> T e2 b -> T e3 c+-- mapT2 = mapT '~@~' fromT+-- @+-- -- This last example is typical for monad transformers: ----- > newtype ErrorT e m a = ErrorT {runErrorT :: m (Either e a)}--- >--- > mapErrorT--- >     :: (m (Either e a) -> m' (Either e' b))--- >     -> ErrorT e m a -> ErrorT e' m' b--- > mapErrorT = ErrorT ~@~ runErrorT--- >--- > mapErrorT2--- >     :: (m1 (Either e1 a) -> m2 (Either e2 b) -> m3 (Either e3 c))--- >     -> ErrorT e1 m1 a -> ErrorT e2 m2 b -> ErrorT e3 m3 c--- > mapErrorT2 = mapErrorT ~@~ runErrorT+-- @+-- newtype ErrorT e m a = ErrorT {runErrorT :: m (Either e a)}+--+-- mapErrorT+--     :: (m (Either e a) -> m' (Either e' b))+--     -> ErrorT e m a -> ErrorT e' m' b+-- mapErrorT = ErrorT '~@~' runErrorT+--+-- mapErrorT2+--     :: (m1 (Either e1 a) -> m2 (Either e2 b) -> m3 (Either e3 c))+--     -> ErrorT e1 m1 a -> ErrorT e2 m2 b -> ErrorT e3 m3 c+-- mapErrorT2 = mapErrorT '~@~' runErrorT+-- @  -- $lenses --@@ -628,61 +281,79 @@ -- -- Lens for a simple newtype: ----- > newtype T a = T {fromT :: a}--- >--- > t :: Functor f => (a -> f b) -> T a -> f (T b)--- > t = fmap T ~@~ fromT+-- @+-- newtype T a = T {fromT :: a} --+-- t :: 'Data.Functor.Functor' f => (a -> f b) -> T a -> f (T b)+-- t = 'Data.Functor.fmap' T '~@~' fromT+-- @+-- -- To simplify things we can use function '<~@~': ----- > t :: Functor f => (a -> f b) -> T a -> f (T b)--- > t = T <~@~ fromT+-- @+-- t :: 'Data.Functor.Functor' f => (a -> f b) -> T a -> f (T b)+-- t = T '<~@~' fromT+-- @ -- -- Lets define lenses for generic data type, e.g. something like: ----- > data D a b = D {_x :: a, _y :: b}+-- @+-- data D a b = D {_x :: a, _y :: b}+-- @ -- -- Their types in /lens/ terms would be: ----- > x :: Lens (D a c) (D b c) a b--- > y :: Lens (D c a) (D c b) a b+-- @+-- x :: Lens (D a c) (D b c) a b+-- y :: Lens (D c a) (D c b) a b+-- @ -- -- Here is how implementation can look like: ----- > x :: Functor f => (a -> f b) -> D a c -> f (D b c)--- > x = _x ~@@^> \s b -> s{_x = b}+-- @+-- x :: 'Data.Functor.Functor' f => (a -> f b) -> D a c -> f (D b c)+-- x = _x '~@@^>' \s b -> s{_x = b}+-- @ -- -- Alternative definitions: ----- > x = (\s b -> s{_x = b}) <^@~ _x--- > x f s = (_x ~@@~> \b -> s{_x = b}) f s--- > x f s = ((\b -> s{_x = b}) <~@~ _x) f s--- > x f s = (const _x ^@@^> \s' b -> s'{_x = b}) f s s--- > x f s = ((\s' b -> s'{_x = b}) <^@^ const _x) f s s+-- @+-- x = (\\s b -> s{_x = b}) '<^@~' _x+-- x f s = (_x '~@@~>' \b -> s{_x = b}) f s+-- x f s = ((\\b -> s{_x = b}) '<~@~' _x) f s+-- x f s = ('Data.Function.const' _x '^@@^>' \\s' b -> s'{_x = b}) f s s+-- x f s = ((\\s' b -> s'{_x = b}) '<^@^' 'Data.Function.const' _x) f s s+-- @ -- -- And now for @y@ we do mostly the same: ----- > y :: Functor f => (a -> f b) -> D c a -> f (D c b)--- > y = _y ~@@^> \s b -> s{_y = b}+-- @+-- y :: 'Data.Functor.Functor' f => (a -> f b) -> D c a -> f (D c b)+-- y = _y '~@@^>' \s b -> s{_y = b}+-- @ -- -- Above example shows us that we are able to define function equivalent to -- @lens@ from /lens/ package as follows: ----- > lens--- >     :: (s -> a)--- >     -- ^ Selector function.--- >     -> (s -> b -> t)--- >     -- ^ Setter function.--- >     -> (forall f. Functor f => (a -> f b) -> s -> f t)--- >     -- ^ In /lens/ terms this is @Lens s t a b@--- > lens = (~@@^>)+-- @+-- lens+--     :: (s -> a)+--     -- ^ Selector function.+--     -> (s -> b -> t)+--     -- ^ Setter function.+--     -> (forall f. 'Data.Functor.Functor' f => (a -> f b) -> s -> f t)+--     -- ^ In \/lens\/ terms this is @Lens s t a b@+-- lens = ('~@@^>')+-- @ -- -- Alternative definitions: ----- > lens get set f s = (const get ^@@^> set) f s s--- > lens get set f s = (set <^@^ const get) f s s--- > lens get set f s = (get ~@~> set s) f s--- > lens get set f s = (set s <~@~ get) f s+-- @+-- lens get set f s = ('Data.Function.const' get '^@@^>' set) f s s+-- lens get set f s = (set '<^@^' 'Data.Function.const' get) f s s+-- lens get set f s = (get '~@~>' set s) f s+-- lens get set f s = (set s '<~@~' get) f s+-- @ -- -- Some other functions from -- <http://hackage.haskell.org/package/lens lens package> can be defined using@@ -699,4 +370,49 @@ -- @ -- -- Data type @Identity@ is defined in--- <http://hackage.haskell.org/package/transformers transformers package>.+-- <http://hackage.haskell.org/package/transformers transformers package> or+-- in base >= 4.8.++-- $profunctors+--+-- You may have noticed similarity between:+--+-- @+-- dimap :: Profunctor p => (a -> b) -> (c -> d) -> p b c -> p a d+-- @+--+-- and+--+-- @+-- between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d+-- @+--+-- If you also consider that there is also @instance Profunctor (->)@, then+-- 'between' becomes specialized @dimap@ for @Profunctor (->)@.+--+-- Profunctors are a powerful abstraction and Edward Kmett's implementation+-- also includes low level optimizations that use the coercible feature of GHC.+-- For more details see its+-- <https://hackage.haskell.org/package/profunctors package documentation>.++-- $pointless-fun+--+-- Package <https://hackage.haskell.org/package/pointless-fun pointless-fun>+-- provides few similar combinators then 'between' in both strict and lazy+-- variants:+--+-- @+-- (~>) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d+-- (!~>) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d+-- @+--+-- Comare it with:+--+-- @+-- 'between' :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d+-- @+--+-- And you see that @(~>)@ is flipped 'Data.Function.Between.Lazy.between' and+-- @(!~>)@ is similar to (strict) 'Data.Function.Between.Strict.between', but+-- our (strict) 'Data.Function.Between.Strict.between' is even less lazy in its+-- implementation then @(!~>)@.
+ src/Data/Function/Between/Lazy.hs view
@@ -0,0 +1,418 @@+{-# LANGUAGE NoImplicitPrelude #-}+-- |+-- Module:       $HEADER$+-- Description:  Lazy function combinator "between" and its variations.+-- Copyright:    (c) 2013-2015 Peter Trško+-- License:      BSD3+--+-- Maintainer:   peter.trsko@gmail.com+-- Stability:    experimental+-- Portability:  NoImplicitPrelude+--+-- Implementation of lazy 'between' combinator and its variations. For+-- introductory documentation see module "Data.Function.Between" and+-- for strict versions import "Data.Function.Between.Strict" module.+--+-- Prior to version 0.10.0.0 functions defined in this module were directly+-- in "Data.Function.Between".+--+-- /Since version 0.10.0.0./+module Data.Function.Between.Lazy+    (+    -- * Between Function Combinator+    --+    -- | Captures common pattern of @\\g -> (f '.' g '.' h)@ where @f@ and @h@+    -- are fixed parameters.+      between+    , (~@~)+    , (~@@~)++    -- * Derived Combinators+    --+    -- | Combinators that either further parametrise @f@ or @g@ in+    -- @f '.' g '.' h@, or apply '~@~' more then once.+    , (^@~)+    , (~@@^)++    , (^@^)+    , (^@@^)++    , between2l+    , between3l++    -- ** Lifted Combinators+    --+    -- | Combinators based on '~@~', '^@~', '^@^', and their flipped variants,+    -- that use 'fmap' to lift one or more of its arguments to operate in+    -- 'Functor' context.+    , (<~@~>)+    , (<~@@~>)++    , (<~@~)+    , (~@@~>)++    , (~@~>)+    , (<~@@~)++    , (<^@~)+    , (~@@^>)++    , (<^@^>)+    , (<^@@^>)++    , (<^@^)+    , (^@@^>)++    , (^@^>)+    , (<^@@^)+    )+  where++import Data.Functor (Functor(fmap))+import Data.Function ((.), flip)+++-- | Core combinator of this module and we build others on top of. It also has+-- an infix form '~@~' and flipped infix form '~@@~'.+--+-- This function Defined as:+--+-- @+-- 'between' f g -> (f .) . (. g)+-- @+between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d+between f g = (f .) . (. g)++-- | Infix variant of 'between'.+--+-- Fixity is left associative and set to value 8, which is one less then fixity+-- of function composition ('.').+(~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d+(~@~) = between+infixl 8 ~@~++-- | Flipped variant of '~@~', i.e. flipped infix variant of 'between'.+--+-- Fixity is right associative and set to value 8, which is one less then+-- fixity of function composition ('.').+(~@@~) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d+(~@@~) = flip between+infixr 8 ~@@~++-- | As '~@~', but first function is also parametrised with @a@, hence the name+-- '^@~'. Character @^@ indicates which argument is parametrised with+-- additional argument.+--+-- This function is defined as:+--+-- @+-- (f '^@~' g) h a -> (f a '~@~' g) h a+-- @+--+-- Fixity is left associative and set to value 8, which is one less then+-- fixity of function composition ('.').+(^@~) :: (a -> c -> d) -> (a -> b) -> (b -> c) -> a -> d+(f ^@~ g) h a = (f a `between` g) h a+infixl 8 ^@~++-- | Flipped variant of '^@~'.+--+-- Fixity is right associative and set to value 8, which is one less then+-- fixity of function composition ('.').+(~@@^) :: (a -> b) -> (a -> c -> d) -> (b -> c) -> a -> d+(~@@^) = flip (^@~)+infixr 8 ~@@^++-- | Pass additional argument to first two function arguments.+--+-- This function is defined as:+--+-- @+-- (f '^@^' g) h a b -> (f a '~@~' g a) h b+-- @+--+-- See also '^@~' to note the difference, most importantly that '^@~' passes+-- the same argument to all its functional arguments. Function '^@~' can be+-- defined in terms of this one as:+--+-- @+-- (f '^@~' g) h a = (f '^@^' 'Data.Function.const' g) h a a+-- @+--+-- We can do it also the other way around and define '^@^' using '^@~':+--+-- @+-- f '^@^' g =+--     'Data.Tuple.curry' . (f . 'Data.Tuple.snd' '^@~' 'Data.Tuple.uncurry' g)+-- @+--+-- Fixity is set to value 8, which is one less then of function composition+-- ('.').+(^@^) :: (a -> d -> e) -> (a -> b -> c) -> (c -> d) -> a -> b -> e+(f ^@^ g) h a = (f a `between` g a) h+infix 8 ^@^++-- | Flipped variant of '^@^'.+--+-- Fixity is set to value 8, which is one less then of function composition+-- ('.').+(^@@^) :: (a -> b -> c) -> (a -> d -> e) -> (c -> d) -> a -> b -> e+(^@@^) = flip (^@^)+infix 8 ^@@^++-- | Apply function @g@ to each argument of binary function and @f@ to its+-- result. In suffix \"2l\" the number is equal to arity of the function it+-- accepts as a third argument and character \"l\" is for \"left associative\".+--+-- @+-- 'between2l' f g = (f '~@~' g) '~@~' g+-- @+--+-- Interesting observation:+--+-- @+-- (\\f g -> 'between2l' 'Data.Function.id' g f) === 'Data.Function.on'+-- @+between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d+between2l f g = (f `between` g) `between` g++-- | Apply function @g@ to each argument of ternary function and @f@ to its+-- result. In suffix \"3l\" the number is equal to arity of the function it+-- accepts as a third argument and character \"l\" is for \"left associative\".+--+-- This function is defined as:+--+-- @+-- 'between3l' f g = ((f '~@~' g) '~@~' g) '~@~' g+-- @+--+-- Alternatively it can be defined using 'between2l':+--+-- @+-- 'between3l' f g = 'between2l' f g '~@~' g+-- @+between3l :: (c -> d) -> (a -> b) -> (b -> b -> b -> c) -> a -> a -> a -> d+between3l f g = ((f `between` g) `between` g) `between` g++-- | Convenience wrapper for:+--+-- @+-- \\f g -> 'fmap' f '~@~' 'fmap' g+-- @+--+-- Name of '<~@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- both its arguments and then we apply '~@~'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition ('.').+(<~@~>)+    :: (Functor f, Functor g)+    => (c -> d) -> (a -> b) -> (f b -> g c) -> f a -> g d+f <~@~> g = fmap f `between` fmap g+infix 8 <~@~>++-- | Flipped variant of '<~@~>'.+--+-- Name of '<~@@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- both its arguments and then we apply '~@@~'.+--+-- Fixity is set to value 8, which is one less then of function composition+-- ('.').+(<~@@~>)+    :: (Functor f, Functor g)+    => (a -> b) -> (c -> d) -> (f b -> g c) -> f a -> g d+g <~@@~> f = fmap f `between` fmap g+infix 8 <~@@~>++-- | Apply fmap to first argument of '~@~'. Dual to '~@~>' which applies+-- 'fmap' to second argument.+--+-- Defined as:+--+-- @+-- f '<~@~' g = 'fmap' f '~@~' g+-- @+--+-- This function allows us to define lenses mostly for pair of functions that+-- form an isomorphism. See section <#g:3 Constructing Lenses> for details.+--+-- Name of '<~@~' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- first (left) argument and then we apply '~@~'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition ('.').+(<~@~) :: Functor f => (c -> d) -> (a -> b) -> (b -> f c) -> a -> f d+(<~@~) = between . fmap+infixl 8 <~@~++-- | Flipped variant of '<~@~'.+--+-- This function allows us to define lenses mostly for pair of functions that+-- form an isomorphism. See section <#g:3 Constructing Lenses> for details.+--+-- Name of '~@@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- second (right) argument and then we apply '~@@~'.+--+-- Fixity is right associative and set to value 8, which is one less then+-- fixity of function composition ('.').+(~@@~>) :: Functor f => (a -> b) -> (c -> d) -> (b -> f c) -> a -> f d+(~@@~>) = flip (<~@~)+infixr 8 ~@@~>++-- | Apply fmap to second argument of '~@~'. Dual to '<~@~' which applies+-- 'fmap' to first argument.+--+-- Defined as:+--+-- @+-- f '~@~>' g -> f '~@~' 'fmap' g+-- @+--+-- Name of '~@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- second (right) argument and then we apply '~@~'.+--+-- Fixity is right associative and set to value 8, which is one less then+-- of function composition ('.').+(~@~>) :: Functor f => (c -> d) -> (a -> b) -> (f b -> c) -> f a -> d+(~@~>) f = between f . fmap+infixl 8 ~@~>++-- | Flipped variant of '~@~>'.+--+-- Name of '<~@@~' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- first (left) argument and then we apply '~@@~'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- fixity of function composition ('.').+(<~@@~) :: Functor f => (a -> b) -> (c -> d) -> (f b -> c) -> f a -> d+(<~@@~) = flip (~@~>)+infixr 8 <~@@~++-- | Convenience wrapper for: @\\f g -> 'fmap' . f '^@~' g@.+--+-- This function has the same functionality as function+--+-- @+-- lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b+-- @+--+-- Which is defined in <http://hackage.haskell.org/package/lens lens package>.+-- Only difference is that arguments of '<^@~' are flipped. See also section+-- <#g:3 Constructing Lenses>.+--+-- Name of '<^@~' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- first (left) arguments and then we apply '^@~'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition ('.').+(<^@~)+    :: Functor f+    => (a -> c -> d) -> (a -> b) -> (b -> f c) -> a -> f d+(<^@~) f = (fmap . f ^@~)+infixl 8 <^@~++-- | Flipped variant of '~@^>'.+--+-- This function has the same functionality as function+--+-- @+-- lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b+-- @+--+-- Which is defined in <http://hackage.haskell.org/package/lens lens package>.+-- See also section <#g:3 Constructing Lenses>.+--+-- Name of '~@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- second (right) arguments and then we apply '~@^>'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition ('.').+(~@@^>)+    :: Functor f+    => (a -> b) -> (a -> c -> d) -> (b -> f c) -> a -> f d+(~@@^>) = flip (<^@~)+infixl 8 ~@@^>++-- | Convenience wrapper for: @\\f g -> 'fmap' . f '^@^' 'fmap' . g@.+--+-- Name of '<^@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- both its arguments and then we apply '^@^'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition ('.').+(<^@^>)+    :: (Functor f, Functor g)+    => (a -> d -> e) -> (a -> b -> c) -> (f c -> g d) -> a -> f b -> g e+(f <^@^> g) h a = (fmap (f a) `between` fmap (g a)) h+infix 8 <^@^>++-- | Flipped variant of '<^@^>'.+--+-- Name of '<^@@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- both its arguments and then we apply '^@@^'.+--+-- Fixity is set to value 8, which is one less then of function composition+-- ('.').+(<^@@^>)+    :: (Functor f, Functor g)+    => (a -> b -> c) -> (a -> d -> e) -> (f c -> g d) -> a -> f b -> g e+(<^@@^>) = flip (<^@^>)+infix 8 <^@@^>++-- | Convenience wrapper for: @\\f g -> 'fmap' . f '^@^' g@.+--+-- This function allows us to define generic lenses from gettern and setter.+-- See section <#g:3 Constructing Lenses> for details.+--+-- Name of '<^@^' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- first (left) arguments and then we apply '^@^'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition ('.').+(<^@^)+    :: Functor f+    => (a -> d -> e) -> (a -> b -> c) -> (c -> f d) -> a -> b -> f e+(f <^@^ g) h a = (fmap (f a) `between` g a) h+infix 8 <^@^++-- | Flipped variant of '<^@^'.+--+-- This function allows us to define generic lenses from gettern and setter.+-- See section <#g:3 Constructing Lenses> for details.+--+-- Name of '^@@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- second (right) arguments and then we apply '^@@^'.+--+-- Fixity is set to value 8, which is one less then of function composition+-- ('.').+(^@@^>)+    :: Functor f+    => (a -> b -> c) -> (a -> d -> e) -> (c -> f d) -> a -> b -> f e+(^@@^>) = flip (<^@^)+infix 8 ^@@^>++-- | Convenience wrapper for: @\\f g -> f '^@^' 'fmap' . g@.+--+-- Name of '^@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- second (right) arguments and then we apply '^@^'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition ('.').+(^@^>)+    :: Functor f+    => (a -> d -> e) -> (a -> b -> c) -> (f c -> d) -> a -> f b -> e+(f ^@^> g) h a = (f a `between` fmap (g a)) h+infix 8 ^@^>++-- | Flipped variant of '^@^>'.+--+-- Name of '<^@@^' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- first (left) arguments and then we apply '^@@^'.+--+-- Fixity is set to value 8, which is one less then of function composition+-- ('.').+(<^@@^)+    :: Functor f+    => (a -> b -> c) -> (a -> d -> e) -> (f c -> d) -> a -> f b -> e+(<^@@^) = flip (^@^>)+infix 8 <^@@^
+ src/Data/Function/Between/Strict.hs view
@@ -0,0 +1,475 @@+{-# LANGUAGE NoImplicitPrelude #-}+-- |+-- Module:       $HEADER$+-- Description:  Strict function combinator "between" and its variations.+-- Copyright:    (c) 2013-2015 Peter Trsko+-- License:      BSD3+--+-- Maintainer:   peter.trsko@gmail.com+-- Stability:    experimental+-- Portability:  NoImplicitPrelude+--+-- Implementation of strict 'between' combinator and its variations. For+-- introductory documentation see module "Data.Function.Between" and+-- for lazy versions import "Data.Function.Between.Lazy" module.+--+-- All functions in this module use strict (or should I say stricter?)+-- definition of function composition:+--+-- @+-- (f . g) x = f '$!' g '$!' x+-- @+--+-- /Since version 0.10.0.0./+module Data.Function.Between.Strict+    (+    -- * Between Function Combinator+    --+    -- | Captures common pattern of @\\g -> (f . g . h)@ where @f@ and @h@+    -- are fixed parameters.+      between+    , (~@~)+    , (~@@~)++    -- * Derived Combinators+    --+    -- | Combinators that either further parametrise @f@ or @g@ in+    -- @f . g . h@, or apply '~@~' more then once.+    , (^@~)+    , (~@@^)++    , (^@^)+    , (^@@^)++    , between2l+    , between3l++    -- ** Lifted Combinators+    --+    -- | Combinators based on '~@~', '^@~', '^@^', and their flipped variants,+    -- that use 'fmap' to lift one or more of its arguments to operate in+    -- 'Functor' context.+    , (<~@~>)+    , (<~@@~>)++    , (<~@~)+    , (~@@~>)++    , (~@~>)+    , (<~@@~)++    , (<^@~)+    , (~@@^>)++    , (<^@^>)+    , (<^@@^>)++    , (<^@^)+    , (^@@^>)++    , (^@^>)+    , (<^@@^)+    )+  where++import Prelude (($!))++import Data.Functor (Functor(fmap))+++-- | Strict variant of function composition. Defined as:+--+-- @+-- (f . g) x = f '$!' g '$!' x+-- @+--+-- Note: this function should not be exported. There are packages out there+-- that provide it and without name clashes.+--+-- /Since version 0.10.0.0./+(.) :: (b -> c) -> (a -> b) -> a -> c+(f . g) x = f $! g $! x+infixr 9 .+{-# INLINE (.) #-}++-- | Core combinator of this module and we build others on top of. It also has+-- an infix form '~@~' and flipped infix form '~@@~'.+--+-- This function Defined as:+--+-- @+-- 'between' f g -> (f .) . (. g)+-- @+--+-- /Since version 0.10.0.0./+between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d+between f g = (f .) . (. g)++-- | Infix variant of 'between'.+--+-- Fixity is left associative and set to value 8, which is one less then fixity+-- of function composition (@.@).+--+-- /Since version 0.10.0.0./+(~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d+(~@~) = between+infixl 8 ~@~++-- | Flipped variant of '~@~', i.e. flipped infix variant of 'between'.+--+-- Fixity is right associative and set to value 8, which is one less then+-- fixity of function composition (@.@).+--+-- /Since version 0.10.0.0./+(~@@~) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d+g ~@@~ f = f `between` g+infixr 8 ~@@~++-- | As '~@~', but first function is also parametrised with @a@, hence the name+-- '^@~'. Character @^@ indicates which argument is parametrised with+-- additional argument.+--+-- This function is defined as:+--+-- @+-- (f '^@~' g) h a -> ((f '$!' a) '~@~' g)) h a+-- @+--+-- Fixity is left associative and set to value 8, which is one less then+-- fixity of function composition (@.@).+--+-- /Since version 0.10.0.0./+(^@~) :: (a -> c -> d) -> (a -> b) -> (b -> c) -> a -> d+(f ^@~ g) h a = ((f $! a) `between` g) h a+infixl 8 ^@~++-- | Flipped variant of '^@~'.+--+-- Fixity is right associative and set to value 8, which is one less then+-- fixity of function composition (@.@).+--+-- /Since version 0.10.0.0./+(~@@^) :: (a -> b) -> (a -> c -> d) -> (b -> c) -> a -> d+g ~@@^ f = f ^@~ g+infixr 8 ~@@^++-- | Pass additional argument to first two function arguments.+--+-- This function is defined as:+--+-- @+-- (f '^@~' g) h a b -> ((f '$!' a) '~@~' (g '$!' a)) h b+-- @+--+-- See also '^@~' to note the difference, most importantly that '^@~' passes+-- the same argument to all its functional arguments. Since this function uses+-- strict function composition and strict application it is not so simple to+-- define it in terms of other combinators in this package and vice versa. See+-- lazy 'Data.Function.Between.^@~' for details.+--+-- Fixity is set to value 8, which is one less then of function composition+-- (@.@).+--+-- /Since version 0.10.0.0./+(^@^) :: (a -> d -> e) -> (a -> b -> c) -> (c -> d) -> a -> b -> e+(f ^@^ g) h a = ((f $! a) `between` (g $! a)) h+infix 8 ^@^++-- | Flipped variant of '^@^'.+--+-- Fixity is set to value 8, which is one less then of function composition+-- (@.@).+--+-- /Since version 0.10.0.0./+(^@@^) :: (a -> b -> c) -> (a -> d -> e) -> (c -> d) -> a -> b -> e+g ^@@^ f = f ^@^ g+infix 8 ^@@^++-- | Apply function @g@ to each argument of binary function and @f@ to its+-- result. In suffix \"2l\" the number is equal to arity of the function it+-- accepts as a third argument and character \"l\" is for \"left associative\".+--+-- @+-- 'between2l' f g = (f '~@~' g) '~@~' g+-- @+--+-- Interesting observation:+--+-- @+-- (\\f g -> 'between2l' 'Data.Function.id' g f) === 'Data.Function.on'+-- @+--+-- /Since version 0.10.0.0./+between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d+between2l f g = (f `between` g) `between` g++-- | Apply function @g@ to each argument of ternary function and @f@ to its+-- result. In suffix \"3l\" the number is equal to arity of the function it+-- accepts as a third argument and character \"l\" is for \"left associative\".+--+-- This function is defined as:+--+-- @+-- 'between3l' f g = ((f '~@~' g) '~@~' g) '~@~' g+-- @+--+-- Alternatively it can be defined using 'between2l':+--+-- @+-- 'between3l' f g = 'between2l' f g '~@~' g+-- @+--+-- /Since version 0.10.0.0./+between3l :: (c -> d) -> (a -> b) -> (b -> b -> b -> c) -> a -> a -> a -> d+between3l f g = ((f `between` g) `between` g) `between` g++-- | Convenience wrapper for:+--+-- @+-- \\f g -> 'fmap' f '~@~' 'fmap' g+-- @+--+-- Name of '<~@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- both its arguments and then we apply '~@~'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition (@.@).+--+-- /Since version 0.10.0.0./+(<~@~>)+    :: (Functor f, Functor g)+    => (c -> d) -> (a -> b) -> (f b -> g c) -> f a -> g d+f <~@~> g = fmap f `between` fmap g+infix 8 <~@~>++-- | Flipped variant of '<~@~>'.+--+-- Name of '<~@@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- both its arguments and then we apply '~@@~'.+--+-- Fixity is set to value 8, which is one less then of function composition+-- (@.@).+--+-- /Since version 0.10.0.0./+(<~@@~>)+    :: (Functor f, Functor g)+    => (a -> b) -> (c -> d) -> (f b -> g c) -> f a -> g d+g <~@@~> f = fmap f `between` fmap g+infix 8 <~@@~>++-- | Apply fmap to first argument of '~@~'. Dual to '~@~>' which applies+-- 'fmap' to second argument.+--+-- Defined as:+--+-- @+-- f '<~@~' g = 'fmap' f '~@~' g+-- @+--+-- This function allows us to define lenses mostly for pair of functions that+-- form an isomorphism. See section <#g:3 Constructing Lenses> for details.+--+-- Name of '<~@~' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- first (left) argument and then we apply '~@~'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition (@.@).+--+-- /Since version 0.10.0.0./+(<~@~) :: Functor f => (c -> d) -> (a -> b) -> (b -> f c) -> a -> f d+f <~@~ g = fmap f `between` g+infixl 8 <~@~++-- | Flipped variant of '<~@~'.+--+-- This function allows us to define lenses mostly for pair of functions that+-- form an isomorphism. See section <#g:3 Constructing Lenses> for details.+--+-- Name of '~@@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- second (right) argument and then we apply '~@@~'.+--+-- Fixity is right associative and set to value 8, which is one less then+-- fixity of function composition (@.@).+--+-- /Since version 0.10.0.0./+(~@@~>) :: Functor f => (a -> b) -> (c -> d) -> (b -> f c) -> a -> f d+g ~@@~> f = f <~@~ g+infixr 8 ~@@~>++-- | Apply fmap to second argument of '~@~'. Dual to '<~@~' which applies+-- 'fmap' to first argument.+--+-- Defined as:+--+-- @+-- f '~@~>' g -> f '~@~' 'fmap' g+-- @+--+-- Name of '~@~>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- second (right) argument and then we apply '~@~'.+--+-- Fixity is right associative and set to value 8, which is one less then+-- of function composition (@.@).+--+-- /Since version 0.10.0.0./+(~@~>) :: Functor f => (c -> d) -> (a -> b) -> (f b -> c) -> f a -> d+f ~@~> g = f `between` fmap g+infixl 8 ~@~>++-- | Flipped variant of '~@~>'.+--+-- Name of '<~@@~' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- first (left) argument and then we apply '~@@~'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- fixity of function composition (@.@).+--+-- /Since version 0.10.0.0./+(<~@@~) :: Functor f => (a -> b) -> (c -> d) -> (f b -> c) -> f a -> d+g <~@@~ f = f ~@~> g+infixr 8 <~@@~++-- | Convenience wrapper for: @\\f g -> 'fmap' . f '^@~' g@.+--+-- This function has the same functionality as function+--+-- @+-- lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b+-- @+--+-- Which is defined in <http://hackage.haskell.org/package/lens lens package>.+-- Only difference is that arguments of '<^@~' are flipped. See also section+-- <#g:3 Constructing Lenses>.+--+-- Name of '<^@~' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- first (left) arguments and then we apply '^@~'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition (@.@).+--+-- /Since version 0.10.0.0./+(<^@~)+    :: Functor f+    => (a -> c -> d) -> (a -> b) -> (b -> f c) -> a -> f d+(<^@~) f = (fmap . f ^@~)+infixl 8 <^@~++-- | Flipped variant of '~@^>'.+--+-- This function has the same functionality as function+--+-- @+-- lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b+-- @+--+-- Which is defined in <http://hackage.haskell.org/package/lens lens package>.+-- See also section <#g:3 Constructing Lenses>.+--+-- Name of '~@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- second (right) arguments and then we apply '~@^>'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition (@.@).+--+-- /Since version 0.10.0.0./+(~@@^>)+    :: Functor f+    => (a -> b) -> (a -> c -> d) -> (b -> f c) -> a -> f d+g ~@@^> f = f <^@~ g+infixl 8 ~@@^>++-- | Convenience wrapper for: @\\f g -> 'fmap' . f '^@^' 'fmap' . g@.+--+-- Name of '<^@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- both its arguments and then we apply '^@^'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition (@.@).+--+-- /Since version 0.10.0.0./+(<^@^>)+    :: (Functor f, Functor g)+    => (a -> d -> e) -> (a -> b -> c) -> (f c -> g d) -> a -> f b -> g e+(f <^@^> g) h a = (fmap (f $! a) `between` fmap (g $! a)) h+infix 8 <^@^>++-- | Flipped variant of '<^@^>'.+--+-- Name of '<^@@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- both its arguments and then we apply '^@@^'.+--+-- Fixity is set to value 8, which is one less then of function composition+-- (@.@).+--+-- /Since version 0.10.0.0./+(<^@@^>)+    :: (Functor f, Functor g)+    => (a -> b -> c) -> (a -> d -> e) -> (f c -> g d) -> a -> f b -> g e+g <^@@^> f = f <^@^> g+infix 8 <^@@^>++-- | Convenience wrapper for: @\\f g -> 'fmap' . f '^@^' g@.+--+-- This function allows us to define generic lenses from gettern and setter.+-- See section <#g:3 Constructing Lenses> for details.+--+-- Name of '<^@^' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- first (left) arguments and then we apply '^@^'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition (@.@).+--+-- /Since version 0.10.0.0./+(<^@^)+    :: Functor f+    => (a -> d -> e) -> (a -> b -> c) -> (c -> f d) -> a -> b -> f e+(f <^@^ g) h a = (fmap (f $! a) `between` (g $! a)) h+infix 8 <^@^++-- | Flipped variant of '<^@^'.+--+-- This function allows us to define generic lenses from gettern and setter.+-- See section <#g:3 Constructing Lenses> for details.+--+-- Name of '^@@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- second (right) arguments and then we apply '^@@^'.+--+-- Fixity is set to value 8, which is one less then of function composition+-- (@.@).+--+-- /Since version 0.10.0.0./+(^@@^>)+    :: Functor f+    => (a -> b -> c) -> (a -> d -> e) -> (c -> f d) -> a -> b -> f e+g ^@@^> f = f <^@^ g+infix 8 ^@@^>++-- | Convenience wrapper for: @\\f g -> f '^@^' 'fmap' . g@.+--+-- Name of '^@^>' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- second (right) arguments and then we apply '^@^'.+--+-- Fixity is left associative and set to value 8, which is one less then+-- of function composition (@.@).+--+-- /Since version 0.10.0.0./+(^@^>)+    :: Functor f+    => (a -> d -> e) -> (a -> b -> c) -> (f c -> d) -> a -> f b -> e+(f ^@^> g) h a = ((f $! a) `between` fmap (g $! a)) h+infix 8 ^@^>++-- | Flipped variant of '^@^>'.+--+-- Name of '<^@@^' simply says that we apply 'Data.Functor.<$>' ('fmap') to+-- first (left) arguments and then we apply '^@@^'.+--+-- Fixity is set to value 8, which is one less then of function composition+-- (@.@).+--+-- /Since version 0.10.0.0./+(<^@@^)+    :: Functor f+    => (a -> b -> c) -> (a -> d -> e) -> (f c -> d) -> a -> f b -> e+g <^@@^ f = f ^@^> g+infix 8 <^@@^