Copyright | (c) Donnacha Oisín Kidney 2018 |
---|---|
License | MIT |
Maintainer | mail@doisinkidney.com |
Portability | GHC |
Safe Haskell | Safe |
Language | Haskell2010 |
Control.Applicative.Lift
Description
There's a family of functions in Control.Applicative which follow the
pattern liftA2
, liftA3
, etc.
Using some tricks from Richard Eisenberg's thesis we can write them all at
once.
- Eisenberg, Richard A. "Dependent Types in Haskell: Theory and Practice." University of Pennsylvania, 2016. https://github.com/goldfirere/thesis/raw/master/built/thesis.pdf
This module exports the one lift
function; for the internal
implementation details see Control.Applicative.Lift.Internal.
Synopsis
- lift :: (Applyable b n, Applicative f) => (a -> b) -> f a -> AppFunc f n b
Documentation
lift :: (Applyable b n, Applicative f) => (a -> b) -> f a -> AppFunc f n b Source #
Lift a function over applicative arguments. This function is an
arity-generic version of the functions liftA2
,
liftA3
, etc.
Type inference works best when the function being lifted is monomorphic:
>>>
lift (\x y z -> x ++ y ++ z) (Just "a") (Just "b") (Just "c")
Just "abc"
In these cases, GHC can see the number of arguments the function must
have, and so is able to pick the correct instance for Applyable
.
If the function is not monomorphic (for instance +
), you will need
to give a type signature:
>>>
lift ((+) :: Int -> Int -> Int) (Just 1) (Just 2)
Just 3
Alternatively, you can use type applications to monomorphise the function:
>>>
:set -XTypeApplications
>>>
lift ((+) @Int) (Just 1) (Just 2)
Just 3
Finally, everything is aggressively inlined, so there should be no
cost to using this function over manually writing
liftA3
etc.