-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Function combinator "between" and derived combinators -- -- It turns out that this combinator -- --
-- 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. -- -- This library not only defines ~@~ combinator, but also some -- derived combinators that can help us easily define a lot of things -- including lenses. See lens package for detais on what lenses -- are. -- -- 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 ---- -- 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 ---- -- Other usage examples and documentation can be found in -- Data.Function.Between module. @package between @version 0.11.0.0 -- | Definitions used by family of strict function combinators. These may -- come handy, but clash with definitions available via Prelude. -- -- Module available since version 0.11.0.0. module Data.Function.Between.Strict.Internal -- | Strict variant of function composition. Defined as: -- --
-- (f . g) x = f $! g $! x ---- -- Internally used since version 0.10.0.0. Moved to -- Data.Function.Between.Strict.Internal module and exposed in -- version 0.11.0.0. (.) :: (b -> c) -> (a -> b) -> a -> c -- | Strict variant of flip. Defined as: -- --
-- flip f b a = f $! a $! b ---- -- Since version 0.11.0.0. flip :: (a -> b -> c) -> b -> a -> c -- | This module defines types that behave as a precursors to types defined -- in lens library. -- -- Since version 0.11.0.0. module Data.Function.Between.Types -- | Family of types that can construct isomorphism between types. -- -- Since version 0.11.0.0. type PreIso r s t a b = ((b -> t) -> (s -> a) -> r) -> r -- | A simple PreIso. -- -- Since version 0.11.0.0. type PreIso' r s a = PreIso r s s a a -- | We can also view PreLens as a special kind of PreIso: -- --
-- PreLens r s t a b = PreIso r s (s -> t) a b ---- -- Since version 0.11.0.0. type PreLens r s t a b = ((b -> s -> t) -> (s -> a) -> r) -> r -- | A simple PreLens, where we can not change the type of the -- information we are focusing on. As a consequence neither the type of -- the container data type can be changed. -- -- Since version 0.11.0.0. type PreLens' r s a = PreLens r s s a a -- | We can also get PrePrism by specializing PreIso: -- --
-- PrePrism r s t a b = PreIso r s t (Either t a) b ---- -- This fact is not surprising, since Prisms are actually a -- special case of isomorphism between two types. -- -- Let's have a type s, and we want to extract specific -- information out of it, but that information may not be there. Because -- of the fact that the type s can be a sum type. Imagine e.g. -- standard Maybe data type: -- --
-- Maybe a = Nothing | Just a ---- -- How do we create something that can extrat that information from a sum -- type, and if necessary, also reconstructs that sum type. The answer is -- Prism, which is defined as an isomorphism between that type -- s and Either t a where a is the -- information we want to extract and t is the rest that we -- don't care about. -- -- You may have noticed, that definition of PrePrism contains some -- type variables that aren't mentioned in the above definition. The -- reason for this is that, as with Lenses we may want to extract -- value of type a, but when constructing new data type we may -- want to change the type of that value in to b and therefore -- type s may not fit, which is the reason why we have type -- t in there. Once again we can ilustrate this with -- Maybe. Lets say that we have a value of s = -- Maybe a, but if we change the type of a in to -- b, and try to create Maybe again, then it would have -- type Maybe b = t. -- -- Since version 0.11.0.0. type PrePrism r s t a b = ((b -> t) -> (s -> Either t a) -> r) -> r -- | A simple PrePrism, where we can not change the type of the -- information we are focusing on. As a consequence neither the type of -- the container data type can be changed. -- -- If we define PrePrism' in terms of PreIso' then we have -- even better ilustration of Prism concept in terms of -- isomorphism: -- --
-- PrePrism' r s a = PreIso' r s (Either t a) ---- -- Since version 0.11.0.0. type PrePrism' r s a = PrePrism r s s a a -- | 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 ---- -- Module available since version 0.10.0.0. module Data.Function.Between.Strict -- | 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 -- | 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 -- | 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 -- | 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 -- | 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 -- | 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 ^@~ 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 -- | 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 -- | 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 id g f) === on ---- -- Since version 0.10.0.0. between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d -- | 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 -- | Convenience wrapper for: -- --
-- \f g -> fmap f ~@~ fmap g ---- -- Name of <~@~> simply says that we apply <$> -- (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 -- | Flipped variant of <~@~>. -- -- Name of <~@@~> simply says that we apply <$> -- (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 -- | 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 Constructing Lenses for -- details. -- -- Name of <~@~ simply says that we apply <$> -- (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 -- | Flipped variant of <~@~. -- -- This function allows us to define lenses mostly for pair of functions -- that form an isomorphism. See section Constructing Lenses for -- details. -- -- Name of ~@@~> simply says that we apply <$> -- (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 -- | 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 <$> -- (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 -- | Flipped variant of ~@~>. -- -- Name of <~@@~ simply says that we apply <$> -- (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 -- | 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 lens package. Only difference is that -- arguments of <^@~ are flipped. See also section -- Constructing Lenses. -- -- Name of <^@~ simply says that we apply <$> -- (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 -- | 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 lens package. See also section -- Constructing Lenses. -- -- Name of ~@^> simply says that we apply <$> -- (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 -- | Convenience wrapper for: \f g -> fmap . f '^^' -- fmap . g@. -- -- Name of <^@^> simply says that we apply <$> -- (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 -- | Flipped variant of <^@^>. -- -- Name of <^@@^> simply says that we apply <$> -- (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 -- | Convenience wrapper for: \f g -> fmap . f '^^' g@. -- -- This function allows us to define generic lenses from gettern and -- setter. See section Constructing Lenses for details. -- -- Name of <^@^ simply says that we apply <$> -- (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 -- | Flipped variant of <^@^. -- -- This function allows us to define generic lenses from gettern and -- setter. See section Constructing Lenses for details. -- -- Name of ^@@^> simply says that we apply <$> -- (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 -- | Convenience wrapper for: \f g -> f '^^' fmap . g@. -- -- Name of ^@^> simply says that we apply <$> -- (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 -- | Flipped variant of ^@^>. -- -- Name of <^@@^ simply says that we apply <$> -- (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 -- | Prefix version of common pattern: -- --
-- \f -> a `f` b ---- -- Where a and b are fixed parameters. There is also -- infix version named ~$~. This function is defined as: -- --
-- inbetween a b f = (f $! a) $! b ---- -- Based on the above definition one can think of it as a variant -- function application that deals with two arguments, where in example -- $ only deals with one. -- -- Since version 0.11.0.0. inbetween :: a -> b -> (a -> b -> r) -> r -- | Infix version of common pattern: -- --
-- \f -> (f $! a) $! b ---- -- Where a and b are fixed parameters. There is also -- prefix version named inbetween. -- -- Since version 0.11.0.0. (~$~) :: a -> b -> (a -> b -> r) -> r -- | Infix version of common pattern: -- --
-- \f -> (f $! a) $! b -- Notice the order of 'a' and 'b'. ---- -- Since version 0.11.0.0. (~$$~) :: b -> a -> (a -> b -> r) -> r -- | Construct a function that encodes idiom: -- --
-- \f -> f $! a $! b -- Notice the order of 'b' and 'a'. ---- -- Function inbetween can be redefined in terms of withIn -- as: -- --
-- a `inbetween` b = withIn $ \f -> a `f` b ---- -- On one hand you can think of this function as a specialized -- id function and on the other as a function application -- $. All the following definitions work for lazy variant: -- --
-- withIn f g = f g -- withIn = id -- withIn = ($) ---- -- For strict variant we use: -- --
-- withIn f g = f $! g ---- -- Usage examples: -- --
-- newtype Foo a = Foo a -- -- inFoo :: ((a -> Foo a) -> (Foo t -> t) -> r) -> r -- inFoo = withIn $ \f -> -- Foo `f` \(Foo a) -> Foo ---- --
-- data Coords2D = Coords2D {_x :: Int, _y :: Int}
--
-- inX :: ((Int -> Coords2D -> Coords2D) -> (Coords2D -> Int) -> r) -> r
-- inX = withIn $ \f ->
-- (\b s -> s{_x = b}) `f` _x
--
--
-- Since version 0.11.0.0.
withIn :: ((a -> b -> r) -> r) -> (a -> b -> r) -> r
-- | Construct a function that encodes idiom:
--
-- -- \f -> b `f` a -- Notice the order of 'b' and 'a'. ---- -- Function ~$$~ can be redefined in terms of withReIn as: -- --
-- b ~$$~ a = withReIn $ \f -> b `f` a ---- -- As withIn, but the function is flipped before applied. All of -- the following definitions work for lazy variant: -- --
-- withReIn f g = f (flip g) -- withReIn = (. flip) ---- -- For strict variant we can use: -- --
-- withReIn f g = f $! \b a -> inbetween a b g -- withReIn f g = f $! \b a -> (a ~$~ b) g -- withReIn f g = f $! \b a -> (b ~$$~ a) g -- withReIn f g = f $! \b a -> g $! a $! b -- withReIn f g = withIn f (\b a -> g $! a $! b) -- withReIn f g = withIn f $! flip $! g -- With strict flip. ---- -- Usage examples: -- --
-- newtype Foo a = Foo a -- -- inFoo :: ((a -> Foo a) -> (Foo t -> t) -> r) -> r -- inFoo = withReIn $ \f -> -- (\(Foo a) -> Foo) `f` Foo ---- --
-- data Coords2D = Coords2D {_x :: Int, _y :: Int}
--
-- inX :: ((Int -> Coords2D -> Coords2D) -> (Coords2D -> Int) -> r) -> r
-- inX = withReIn $ \f ->
-- _x `f` \b s -> s{_x = b}
--
--
-- Since version 0.11.0.0.
withReIn :: ((b -> a -> r) -> r) -> (a -> b -> r) -> r
-- | Family of types that can construct isomorphism between types.
--
-- Since version 0.11.0.0.
type PreIso r s t a b = ((b -> t) -> (s -> a) -> r) -> r
-- | A simple PreIso.
--
-- Since version 0.11.0.0.
type PreIso' r s a = PreIso r s s a a
-- | Construct a PreIso; this function similar to Iso
-- constructor function from lens package:
--
-- -- iso :: (s -> a) -> (b -> t) -> Iso s t a b ---- -- Usage example: -- --
-- data Foo a = Foo a -- -- preFoo :: PreIso r (Foo a) (Foo b) a b -- preFoo = Foo `preIso` \(Foo a) -> a --preIso :: (s -> a) -> (b -> t) -> PreIso r s t a b -- | Flipped variant of preIso. -- -- Usage example: -- --
-- data Foo a = Foo {_getFoo :: a}
--
-- preFoo :: PreIso r (Foo a) (Foo b) a b
-- preFoo = _getFoo `preIso'` Foo
--
preIso' :: (b -> t) -> (s -> a) -> PreIso r s t a b
-- | We can also view PreLens as a special kind of PreIso:
--
-- -- PreLens r s t a b = PreIso r s (s -> t) a b ---- -- Since version 0.11.0.0. type PreLens r s t a b = ((b -> s -> t) -> (s -> a) -> r) -> r -- | A simple PreLens, where we can not change the type of the -- information we are focusing on. As a consequence neither the type of -- the container data type can be changed. -- -- Since version 0.11.0.0. type PreLens' r s a = PreLens r s s a a -- | Construct a PreLens; this function is similar to Lens -- constructor function from lens package: -- --
-- lens :: (s -> b -> t) -> (s -> a) -> Lens' s t a b ---- -- Usage example: -- --
-- data Coords2D = Coords2D {_x :: Int, _y :: Int}
--
-- preX :: PreLens' r Coords2D Int
-- preX = (\s b -> s{_x = b}) `preLens` _x
--
preLens :: (s -> b -> t) -> (s -> a) -> PreLens r s t a b
-- | Flipped version of preLens that takes getter first and setter
-- second.
--
--
-- data Coords2D = Coords2D {_x :: Int, _y :: Int}
--
-- preX :: PreLens' r Coords2D Int
-- preX = _x `preLens'` \s b -> s{_x = b}
--
preLens' :: (s -> a) -> (s -> b -> t) -> PreLens r s t a b
-- | Convert PreIso in to PreLens by injecting const to a
-- setter function.
--
-- -- preIsoToPreLens aPreIso f = aPreIso $ \fbt fsa -> const fbt `f` fsa --preIsoToPreLens :: PreIso r s t a b -> PreLens r s t a b -- | Construct a Lens out of a PreLens. -- --
-- data Coords2D = Coords2D {_x :: Int, _y :: Int}
--
-- preX :: PreLens' r Coords2D Int
-- preX = _x `preLens'` \s b -> s{_x = b}
--
-- x :: Lens' Coords2D Int
-- x = le preX
--
le :: Functor f => PreLens ((a -> f b) -> s -> f t) s t a b -> (a -> f b) -> s -> f t
-- | We can also get PrePrism by specializing PreIso:
--
-- -- PrePrism r s t a b = PreIso r s t (Either t a) b ---- -- This fact is not surprising, since Prisms are actually a -- special case of isomorphism between two types. -- -- Let's have a type s, and we want to extract specific -- information out of it, but that information may not be there. Because -- of the fact that the type s can be a sum type. Imagine e.g. -- standard Maybe data type: -- --
-- Maybe a = Nothing | Just a ---- -- How do we create something that can extrat that information from a sum -- type, and if necessary, also reconstructs that sum type. The answer is -- Prism, which is defined as an isomorphism between that type -- s and Either t a where a is the -- information we want to extract and t is the rest that we -- don't care about. -- -- You may have noticed, that definition of PrePrism contains some -- type variables that aren't mentioned in the above definition. The -- reason for this is that, as with Lenses we may want to extract -- value of type a, but when constructing new data type we may -- want to change the type of that value in to b and therefore -- type s may not fit, which is the reason why we have type -- t in there. Once again we can ilustrate this with -- Maybe. Lets say that we have a value of s = -- Maybe a, but if we change the type of a in to -- b, and try to create Maybe again, then it would have -- type Maybe b = t. -- -- Since version 0.11.0.0. type PrePrism r s t a b = ((b -> t) -> (s -> Either t a) -> r) -> r -- | A simple PrePrism, where we can not change the type of the -- information we are focusing on. As a consequence neither the type of -- the container data type can be changed. -- -- If we define PrePrism' in terms of PreIso' then we have -- even better ilustration of Prism concept in terms of -- isomorphism: -- --
-- PrePrism' r s a = PreIso' r s (Either t a) ---- -- Since version 0.11.0.0. type PrePrism' r s a = PrePrism r s s a a -- | Constract a PrePrism; this function is similar to Prism -- constructor function from lens package: -- --
-- prism :: (b -> t) -> (s -> Either t a) -> Prism s t a b ---- -- Usage example: -- --
-- {-# LANGUAGE LambdaCase #-}
-- data Sum a b = A a | B b
--
-- preA :: PrePrism r (Sum a c) (Sum b c) a b
-- preA = prePrism A $ \case
-- A a -> Right a
-- B b -> Left (B b)
--
prePrism :: (b -> t) -> (s -> Either t a) -> PrePrism r s t a b
-- | Simplified construction of PrePrism, which can be used in
-- following situations:
--
-- -- prePrism' :: PreIso r s s (Maybe a) b -> PrePrism r s s a b --prePrism' :: (b -> s) -> (s -> Maybe a) -> PrePrism r s s a b -- | 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. -- -- Module available since version 0.10.0.0. module 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 -- | 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 -- | 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 -- | 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 -- | 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 -- | 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 ^@^ const g) h a a ---- -- We can do it also the other way around and define ^@^ using -- ^@~: -- --
-- f ^@^ g = -- curry . (f . snd ^@~ 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 -- | 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 -- | 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 id g f) === on --between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d -- | 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 -- | Convenience wrapper for: -- --
-- \f g -> fmap f ~@~ fmap g ---- -- Name of <~@~> simply says that we apply <$> -- (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 -- | Flipped variant of <~@~>. -- -- Name of <~@@~> simply says that we apply <$> -- (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 -- | 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 Constructing Lenses for -- details. -- -- Name of <~@~ simply says that we apply <$> -- (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 -- | Flipped variant of <~@~. -- -- This function allows us to define lenses mostly for pair of functions -- that form an isomorphism. See section Constructing Lenses for -- details. -- -- Name of ~@@~> simply says that we apply <$> -- (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 -- | 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 <$> -- (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 -- | Flipped variant of ~@~>. -- -- Name of <~@@~ simply says that we apply <$> -- (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 -- | 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 lens package. Only difference is that -- arguments of <^@~ are flipped. See also section -- Constructing Lenses. -- -- Name of <^@~ simply says that we apply <$> -- (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 -- | 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 lens package. See also section -- Constructing Lenses. -- -- Name of ~@^> simply says that we apply <$> -- (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 -- | Convenience wrapper for: \f g -> fmap . f '^^' -- fmap . g@. -- -- Name of <^@^> simply says that we apply <$> -- (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 -- | Flipped variant of <^@^>. -- -- Name of <^@@^> simply says that we apply <$> -- (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 -- | Convenience wrapper for: \f g -> fmap . f '^^' g@. -- -- This function allows us to define generic lenses from gettern and -- setter. See section Constructing Lenses for details. -- -- Name of <^@^ simply says that we apply <$> -- (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 -- | Flipped variant of <^@^. -- -- This function allows us to define generic lenses from gettern and -- setter. See section Constructing Lenses for details. -- -- Name of ^@@^> simply says that we apply <$> -- (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 -- | Convenience wrapper for: \f g -> f '^^' fmap . g@. -- -- Name of ^@^> simply says that we apply <$> -- (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 -- | Flipped variant of ^@^>. -- -- Name of <^@@^ simply says that we apply <$> -- (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 -- | Prefix version of common pattern: -- --
-- \f -> a `f` b ---- -- Where a and b are fixed parameters. There is also -- infix version named ~$~. This function is defined as: -- --
-- inbetween a b f = f a b ---- -- Based on the above definition one can think of it as a variant -- function application that deals with two arguments, where in example -- $ only deals with one. -- -- Since version 0.11.0.0. inbetween :: a -> b -> (a -> b -> r) -> r -- | Infix version of common pattern: -- --
-- \f -> a `f` b ---- -- Where a and b are fixed parameters. There is also -- prefix version named inbetween. -- -- Since version 0.11.0.0. (~$~) :: a -> b -> (a -> b -> r) -> r -- | Infix version of common pattern: -- --
-- \f -> a `f` b -- Notice the order of 'a' and 'b'. ---- -- Since version 0.11.0.0. (~$$~) :: b -> a -> (a -> b -> r) -> r -- | Construct a function that encodes idiom: -- --
-- \f -> a `f` b -- Notice the order of 'b' and 'a'. ---- -- Function inbetween can be redefined in terms of withIn -- as: -- --
-- a `inbetween` b = withIn $ \f -> a `f` b ---- -- On one hand you can think of this function as a specialized id -- function and on the other as a function application $. All the -- following definitions work: -- --
-- withIn f g = f g -- withIn = id -- withIn = ($) ---- -- Usage examples: -- --
-- newtype Foo a = Foo a -- -- inFoo :: ((a -> Foo a) -> (Foo t -> t) -> r) -> r -- inFoo = withIn $ \f -> -- Foo `f` \(Foo a) -> Foo ---- --
-- data Coords2D = Coords2D {_x :: Int, _y :: Int}
--
-- inX :: ((Int -> Coords2D -> Coords2D) -> (Coords2D -> Int) -> r) -> r
-- inX = withIn $ \f ->
-- (\b s -> s{_x = b}) `f` _x
--
--
-- Since version 0.11.0.0.
withIn :: ((a -> b -> r) -> r) -> (a -> b -> r) -> r
-- | Construct a function that encodes idiom:
--
-- -- \f -> b `f` a -- Notice the order of 'b' and 'a'. ---- -- Function ~$$~ can be redefined in terms of withReIn as: -- --
-- b ~$$~ a = withReIn $ \f -> b `f` a ---- -- As withIn, but the function is flipped before applied. All of -- the following definitions work: -- --
-- withReIn f g = f (flip g) -- withReIn = (. flip) ---- -- Usage examples: -- --
-- newtype Foo a = Foo a -- -- inFoo :: ((a -> Foo a) -> (Foo t -> t) -> r) -> r -- inFoo = withReIn $ \f -> -- (\(Foo a) -> Foo) `f` Foo ---- --
-- data Coords2D = Coords2D {_x :: Int, _y :: Int}
--
-- inX :: ((Int -> Coords2D -> Coords2D) -> (Coords2D -> Int) -> r) -> r
-- inX = withReIn $ \f ->
-- _x `f` \b s -> s{_x = b}
--
--
-- Since version 0.11.0.0.
withReIn :: ((b -> a -> r) -> r) -> (a -> b -> r) -> r
-- | Family of types that can construct isomorphism between types.
--
-- Since version 0.11.0.0.
type PreIso r s t a b = ((b -> t) -> (s -> a) -> r) -> r
-- | A simple PreIso.
--
-- Since version 0.11.0.0.
type PreIso' r s a = PreIso r s s a a
-- | Construct a PreIso; this function similar to Iso
-- constructor function from lens package:
--
-- -- iso :: (s -> a) -> (b -> t) -> Iso s t a b ---- -- Usage example: -- --
-- data Foo a = Foo a -- -- preFoo :: PreIso r (Foo a) (Foo b) a b -- preFoo = Foo `preIso` \(Foo a) -> a --preIso :: (s -> a) -> (b -> t) -> PreIso r s t a b -- | Flipped variant of preIso. -- -- Usage example: -- --
-- data Foo a = Foo {_getFoo :: a}
--
-- preFoo :: PreIso r (Foo a) (Foo b) a b
-- preFoo = _getFoo `preIso'` Foo
--
preIso' :: (b -> t) -> (s -> a) -> PreIso r s t a b
-- | We can also view PreLens as a special kind of PreIso:
--
-- -- PreLens r s t a b = PreIso r s (s -> t) a b ---- -- Since version 0.11.0.0. type PreLens r s t a b = ((b -> s -> t) -> (s -> a) -> r) -> r -- | A simple PreLens, where we can not change the type of the -- information we are focusing on. As a consequence neither the type of -- the container data type can be changed. -- -- Since version 0.11.0.0. type PreLens' r s a = PreLens r s s a a -- | Construct a PreLens; this function is similar to Lens -- constructor function from lens package: -- --
-- lens :: (s -> b -> t) -> (s -> a) -> Lens' s t a b ---- -- Usage example: -- --
-- data Coords2D = Coords2D {_x :: Int, _y :: Int}
--
-- preX :: PreLens' r Coords2D Int
-- preX = (\s b -> s{_x = b}) `preLens` _x
--
preLens :: (s -> b -> t) -> (s -> a) -> PreLens r s t a b
-- | Flipped version of preLens that takes getter first and setter
-- second.
--
--
-- data Coords2D = Coords2D {_x :: Int, _y :: Int}
--
-- preX :: PreLens' r Coords2D Int
-- preX = _x `preLens'` \s b -> s{_x = b}
--
preLens' :: (s -> a) -> (s -> b -> t) -> PreLens r s t a b
-- | Convert PreIso in to PreLens by injecting const to a
-- setter function.
--
-- -- preIsoToPreLens aPreIso f = aPreIso $ \fbt fsa -> const fbt `f` fsa --preIsoToPreLens :: PreIso r s t a b -> PreLens r s t a b -- | Construct a Lens out of a PreLens. -- --
-- data Coords2D = Coords2D {_x :: Int, _y :: Int}
--
-- preX :: PreLens' r Coords2D Int
-- preX = _x `preLens'` \s b -> s{_x = b}
--
-- x :: Lens' Coords2D Int
-- x = le preX
--
le :: Functor f => PreLens ((a -> f b) -> s -> f t) s t a b -> (a -> f b) -> s -> f t
-- | We can also get PrePrism by specializing PreIso:
--
-- -- PrePrism r s t a b = PreIso r s t (Either t a) b ---- -- This fact is not surprising, since Prisms are actually a -- special case of isomorphism between two types. -- -- Let's have a type s, and we want to extract specific -- information out of it, but that information may not be there. Because -- of the fact that the type s can be a sum type. Imagine e.g. -- standard Maybe data type: -- --
-- Maybe a = Nothing | Just a ---- -- How do we create something that can extrat that information from a sum -- type, and if necessary, also reconstructs that sum type. The answer is -- Prism, which is defined as an isomorphism between that type -- s and Either t a where a is the -- information we want to extract and t is the rest that we -- don't care about. -- -- You may have noticed, that definition of PrePrism contains some -- type variables that aren't mentioned in the above definition. The -- reason for this is that, as with Lenses we may want to extract -- value of type a, but when constructing new data type we may -- want to change the type of that value in to b and therefore -- type s may not fit, which is the reason why we have type -- t in there. Once again we can ilustrate this with -- Maybe. Lets say that we have a value of s = -- Maybe a, but if we change the type of a in to -- b, and try to create Maybe again, then it would have -- type Maybe b = t. -- -- Since version 0.11.0.0. type PrePrism r s t a b = ((b -> t) -> (s -> Either t a) -> r) -> r -- | A simple PrePrism, where we can not change the type of the -- information we are focusing on. As a consequence neither the type of -- the container data type can be changed. -- -- If we define PrePrism' in terms of PreIso' then we have -- even better ilustration of Prism concept in terms of -- isomorphism: -- --
-- PrePrism' r s a = PreIso' r s (Either t a) ---- -- Since version 0.11.0.0. type PrePrism' r s a = PrePrism r s s a a -- | Constract a PrePrism; this function is similar to Prism -- constructor function from lens package: -- --
-- prism :: (b -> t) -> (s -> Either t a) -> Prism s t a b ---- -- Usage example: -- --
-- {-# LANGUAGE LambdaCase #-}
-- data Sum a b = A a | B b
--
-- preA :: PrePrism r (Sum a c) (Sum b c) a b
-- preA = prePrism A $ \case
-- A a -> Right a
-- B b -> Left (B b)
--
prePrism :: (b -> t) -> (s -> Either t a) -> PrePrism r s t a b
-- | Simplified construction of PrePrism, which can be used in
-- following situations:
--
-- -- prePrism' :: PreIso r s s (Maybe a) b -> PrePrism r s s a b --prePrism' :: (b -> s) -> (s -> Maybe a) -> PrePrism r s s a b -- | During development it is common occurrence to modify deeply nested -- structures. One of the best known libraries for this purpose is -- lens, but it's quite overkill for some purposes. -- -- This library describes simple and composable combinators that are -- built on top of few very basic concepts. First one is: -- --
-- \h -> f . h . g ---- -- Where f and g are fixed and h is a free -- variable. It is possible to reduce it to just: -- --
-- (f .) . (. g) ---- -- Which is one of the core pattern used by all related functions defined -- in this module. -- -- Trying to generalize this pattern further ends as (f -- <$>) . (<$> g), where -- <$> = fmap. Other combinations of -- substituting . for 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 ---- -- Which doesn't give us much more power. Instead of going for such -- generalization we kept the original ((f .) . (. g)) which we -- named between or ~@~ in its infix form. There are other -- possible generalizations possible, in example by using . from -- Control.Category or by using composition from -- Semigroupoid class, but that requires dependency on -- semigroupoids package. -- -- Second concept/pattern exploited in this package is infix function -- application with two arguments: -- --
-- \(<>) -> a <> b ---- -- Where a and b are fixed and <> is a -- free variable. This library defines inbetween operator (also -- called ~$~, in its infix form) that embodies mentioned pattern: -- --
-- inbetween :: a -> b -> (a -> b -> r) -> r -- inbetween a b f = a `f` b ---- --
-- (~$~) :: a -> b -> (a -> b -> r) -> r -- (a ~$~ b) (<>) = a <> b --module Data.Function.Between