ap package:ghc-internal

In many situations, the liftM operations can be replaced by uses of ap, which promotes function application.
return f `ap` x1 `ap` ... `ap` xn
is equivalent to
liftM<n> f x1 x2 ... xn

Examples

>>> pure (\x y z -> x + y * z) `ap` Just 1 `ap` Just 5 `ap` Just 10
Just 51
This data type witnesses the lifting of a Monoid into an Applicative pointwise.

Examples

>>> Ap (Just [1, 2, 3]) <> Ap Nothing
Ap {getAp = Nothing}
>>> Ap [Sum 10, Sum 20] <> Ap [Sum 1, Sum 2]
Ap {getAp = [Sum {getSum = 11},Sum {getSum = 12},Sum {getSum = 21},Sum {getSum = 22}]}
applyWhen applies a function to a value if a condition is true, otherwise, it returns the value unchanged. It is equivalent to flip (bool id).

Examples

>>> map (\x -> applyWhen (odd x) (*2) x) [1..10]
[2,2,6,4,10,6,14,8,18,10]
>>> map (\x -> applyWhen (length x > 6) ((++ "...") . take 3) x) ["Hi!", "This is amazing", "Hope you're doing well today!", ":D"]
["Hi!","Thi...","Hop...",":D"]

Algebraic properties

a
The computation appendFile file str function appends the string str, to the file file. Note that writeFile and appendFile write a literal string to a file. To write a value of any printable type, as with print, use the show function to convert the value to a string first. This operation may fail with the same errors as hPutStr and withFile.

Examples

The following example could be more efficently written by acquiring a handle instead with openFile and using the computations capable of writing to handles such as hPutStr.
>>> let fn = "hello_world"

>>> in writeFile fn "hello" >> appendFile fn " world!" >> (readFile fn >>= putStrLn)
"hello world!"
>>> let fn = "foo"; output = readFile' fn >>= putStrLn

>>> in output >> appendFile fn (show [1,2,3]) >> output
this is what's in the file
this is what's in the file[1,2,3]
A functor with application, providing operations to
  • embed pure expressions (pure), and
  • sequence computations and combine their results (<*> and liftA2).
A minimal complete definition must include implementations of pure and of either <*> or liftA2. If it defines both, then they must behave the same as their default definitions:
(<*>) = liftA2 id
liftA2 f x y = f <$> x <*> y
Further, any definition must satisfy the following: The other methods have the following default definitions, which may be overridden with equivalent specialized implementations: As a consequence of these laws, the Functor instance for f will satisfy It may be useful to note that supposing
forall x y. p (q x y) = f x . g y
it follows from the above that
liftA2 p (liftA2 q u v) = liftA2 f u . liftA2 g v
If f is also a Monad, it should satisfy (which implies that pure and <*> satisfy the applicative functor laws).
{ f x }
T @k t
T a b