| Copyright | (c) 2013-2015, Peter Trško |
|---|---|
| License | BSD3 |
| Maintainer | peter.trsko@gmail.com |
| Stability | experimental |
| Portability | NoImplicitPrelude |
| Safe Haskell | Safe |
| Language | Haskell98 |
Data.Function.Between.Strict
Contents
Description
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.
- between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
- (~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
- (~@@~) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d
- (^@~) :: (a -> c -> d) -> (a -> b) -> (b -> c) -> a -> d
- (~@@^) :: (a -> b) -> (a -> c -> d) -> (b -> c) -> a -> d
- (^@^) :: (a -> d -> e) -> (a -> b -> c) -> (c -> d) -> a -> b -> e
- (^@@^) :: (a -> b -> c) -> (a -> d -> e) -> (c -> d) -> a -> b -> e
- between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d
- between3l :: (c -> d) -> (a -> b) -> (b -> b -> b -> c) -> a -> a -> a -> d
- (<~@~>) :: (Functor f, Functor g) => (c -> d) -> (a -> b) -> (f b -> g c) -> f a -> g d
- (<~@@~>) :: (Functor f, Functor g) => (a -> b) -> (c -> d) -> (f b -> g c) -> f a -> g d
- (<~@~) :: Functor f => (c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
- (~@@~>) :: Functor f => (a -> b) -> (c -> d) -> (b -> f c) -> a -> f d
- (~@~>) :: Functor f => (c -> d) -> (a -> b) -> (f b -> c) -> f a -> d
- (<~@@~) :: Functor f => (a -> b) -> (c -> d) -> (f b -> c) -> f a -> d
- (<^@~) :: Functor f => (a -> c -> d) -> (a -> b) -> (b -> f c) -> a -> f d
- (~@@^>) :: Functor f => (a -> b) -> (a -> c -> d) -> (b -> f c) -> a -> f d
- (<^@^>) :: (Functor f, Functor g) => (a -> d -> e) -> (a -> b -> c) -> (f c -> g d) -> a -> f b -> g e
- (<^@@^>) :: (Functor f, Functor g) => (a -> b -> c) -> (a -> d -> e) -> (f c -> g d) -> a -> f b -> g e
- (<^@^) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (c -> f d) -> a -> b -> f e
- (^@@^>) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (c -> f d) -> a -> b -> f e
- (^@^>) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (f c -> d) -> a -> f b -> e
- (<^@@^) :: Functor f => (a -> b -> c) -> (a -> d -> e) -> (f c -> d) -> a -> f b -> e
- inbetween :: a -> b -> (a -> b -> r) -> r
- (~$~) :: a -> b -> (a -> b -> r) -> r
- (~$$~) :: b -> a -> (a -> b -> r) -> r
- withIn :: ((a -> b -> r) -> r) -> (a -> b -> r) -> r
- withReIn :: ((b -> a -> r) -> r) -> (a -> b -> r) -> r
- type PreIso r s t a b = ((b -> t) -> (s -> a) -> r) -> r
- type PreIso' r s a = PreIso r s s a a
- preIso :: (s -> a) -> (b -> t) -> PreIso r s t a b
- preIso' :: (b -> t) -> (s -> a) -> PreIso r s t a b
- type PreLens r s t a b = ((b -> s -> t) -> (s -> a) -> r) -> r
- type PreLens' r s a = PreLens r s s a a
- preLens :: (s -> b -> t) -> (s -> a) -> PreLens r s t a b
- preLens' :: (s -> a) -> (s -> b -> t) -> PreLens r s t a b
- preIsoToPreLens :: PreIso r s t a b -> PreLens r s t a b
- le :: Functor f => PreLens ((a -> f b) -> s -> f t) s t a b -> (a -> f b) -> s -> f t
- type PrePrism r s t a b = ((b -> t) -> (s -> Either t a) -> r) -> r
- type PrePrism' r s a = PrePrism r s s a a
- prePrism :: (b -> t) -> (s -> Either t a) -> PrePrism r s t a b
- prePrism' :: (b -> s) -> (s -> Maybe a) -> PrePrism r s s a b
Between Function Combinator
Captures common pattern of \g -> (f . g . h) where f and h
are fixed parameters and (.) is strict function composition.
(~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d infixl 8 Source
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.
Derived Combinators
Combinators that either further parametrise f or g in
f . g . h, or apply ~@~ more then once.
(^@~) :: (a -> c -> d) -> (a -> b) -> (b -> c) -> a -> d infixl 8 Source
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 -> b) -> (a -> c -> d) -> (b -> c) -> a -> d infixr 8 Source
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 -> d -> e) -> (a -> b -> c) -> (c -> d) -> a -> b -> e infix 8 Source
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 -> b -> c) -> (a -> d -> e) -> (c -> d) -> a -> b -> e infix 8 Source
Flipped variant of ^@^.
Fixity is set to value 8, which is one less then of function composition
(.).
Since version 0.10.0.0.
between2l :: (c -> d) -> (a -> b) -> (b -> b -> c) -> a -> a -> d Source
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".
between2lf g = (f~@~g)~@~g
Interesting observation:
(\f g ->between2lidg f) ===on
Since version 0.10.0.0.
between3l :: (c -> d) -> (a -> b) -> (b -> b -> b -> c) -> a -> a -> a -> d Source
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:
between3lf g = ((f~@~g)~@~g)~@~g
Alternatively it can be defined using between2l:
between3lf g =between2lf g~@~g
Since version 0.10.0.0.
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.
(<~@~>) :: (Functor f, Functor g) => (c -> d) -> (a -> b) -> (f b -> g c) -> f a -> g d infix 8 Source
(<~@@~>) :: (Functor f, Functor g) => (a -> b) -> (c -> d) -> (f b -> g c) -> f a -> g d infix 8 Source
(<~@~) :: Functor f => (c -> d) -> (a -> b) -> (b -> f c) -> a -> f d infixl 8 Source
Apply fmap to first argument of ~@~. Dual to ~@~> which applies
fmap to second argument.
Defined as:
f<~@~g =fmapf~@~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 => (a -> b) -> (c -> d) -> (b -> f c) -> a -> f d infixr 8 Source
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 => (c -> d) -> (a -> b) -> (f b -> c) -> f a -> d infixl 8 Source
Apply fmap to second argument of ~@~. Dual to <~@~ which applies
fmap to first argument.
Defined as:
f~@~>g -> f~@~fmapg
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 => (a -> c -> d) -> (a -> b) -> (b -> f c) -> a -> f d infixl 8 Source
Convenience wrapper for: \f g -> ~' g@.fmap . f '^
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 -> b) -> (a -> c -> d) -> (b -> f c) -> a -> f d infixl 8 Source
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, Functor g) => (a -> d -> e) -> (a -> b -> c) -> (f c -> g d) -> a -> f b -> g e infix 8 Source
(<^@@^>) :: (Functor f, Functor g) => (a -> b -> c) -> (a -> d -> e) -> (f c -> g d) -> a -> f b -> g e infix 8 Source
(<^@^) :: Functor f => (a -> d -> e) -> (a -> b -> c) -> (c -> f d) -> a -> b -> f e infix 8 Source
Convenience wrapper for: \f g -> ^' g@.fmap . f '^
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 -> b -> c) -> (a -> d -> e) -> (c -> f d) -> a -> b -> f e infix 8 Source
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) -> (f c -> d) -> a -> f b -> e infix 8 Source
In-Between Function Application Combinator
Captures common pattern of \f -> (a `f` b) where a and b are
fixed parameters. It doesn't look impressive untill one thinks about a
and b as functions.
Since version 0.11.0.0.
inbetween :: a -> b -> (a -> b -> r) -> r infix 8 Source
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.
withIn :: ((a -> b -> r) -> r) -> (a -> b -> r) -> r Source
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:
withInf g = f gwithIn=idwithIn= ($)
For strict variant we use:
withInf 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.
withReIn :: ((b -> a -> r) -> r) -> (a -> b -> r) -> r Source
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:
withReInf g = f (flipg)withReIn= (.flip)
For strict variant we can use:
withReInf g = f$!\b a ->inbetweena b gwithReInf g = f$!\b a -> (a~$~b) gwithReInf g = f$!\b a -> (b~$$~a) gwithReInf g = f$!\b a -> g$!a$!bwithReInf g =withInf (\b a -> g$!a$!b)withReInf g =withInf $!flip$! g -- With strictflip.
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.
Precursors to Iso, Lens and Prism
Since version 0.11.0.0.
PreIso
type PreIso r s t a b = ((b -> t) -> (s -> a) -> r) -> r Source
Family of types that can construct isomorphism between types.
Since version 0.11.0.0.
PreLens
type PreLens' r s a = PreLens r s s a a Source
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.
preIsoToPreLens :: PreIso r s t a b -> PreLens r s t a b Source
Convert PreIso in to PreLens by injecting const to a setter function.
preIsoToPreLensaPreIso f = aPreIso$\fbt fsa ->constfbt `f` fsa
PrePrism
type PrePrism r s t a b = ((b -> t) -> (s -> Either t a) -> r) -> r Source
We can also get PrePrism by specializing PreIso:
PrePrismr s t a b =PreIsor s t (Eithert 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:
Maybea =Nothing|Justa
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
where Either t aa 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 = , but if we change the type of Maybe aa 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 a = PrePrism r s s a a Source
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 (Eithert a)
Since version 0.11.0.0.
prePrism :: (b -> t) -> (s -> Either t a) -> PrePrism r s t a b Source
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 -> s) -> (s -> Maybe a) -> PrePrism r s s a b Source
Simplified construction of PrePrism, which can be used in following
situations:
- Constructing Prism for types isomorphic to
Maybeor - when using
castoperation, or similar, which either returns what you want orNothing.
Alternative type signature of this function is also:
prePrism'::PreIsor s s (Maybea) b ->PrePrismr s s a b