arity-generic-liftA-0.1.0.0: Provides an arity-generic version of the liftA2, liftA3... liftAn functions.

Copyright(c) Donnacha Oisín Kidney 2018
LicenseMIT
Maintainermail@doisinkidney.com
PortabilityGHC
Safe HaskellSafe
LanguageHaskell2010

Control.Applicative.Lift.Internal

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.

Synopsis

Documentation

data N Source #

Simple implementation of Peano numbers.

Constructors

Z 
S N 

type family AppFunc f n a where ... Source #

AppFunc f n a returns the type of the function a "lifted" over n arguments.

Equations

AppFunc f Z a = f a 
AppFunc f (S n) (a -> b) = f a -> AppFunc f n b 

type family CountArgs f where ... Source #

Counts the arguments of a function

Equations

CountArgs (_ -> b) = S (CountArgs b) 
CountArgs _ = Z 

class CountArgs a ~ n => Applyable a n where Source #

The actual class which constructs the lifted function.

Methods

apply :: Applicative f => f a -> AppFunc f (CountArgs a) a Source #

Instances
CountArgs a ~ Z => Applyable a Z Source # 
Instance details

Defined in Control.Applicative.Lift.Internal

Methods

apply :: Applicative f => f a -> AppFunc f (CountArgs a) a Source #

Applyable b n => Applyable (a -> b) (S n) Source # 
Instance details

Defined in Control.Applicative.Lift.Internal

Methods

apply :: Applicative f => f (a -> b) -> AppFunc f (CountArgs (a -> b)) (a -> b) Source #

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.