acme-functors-0.1.0.1: The best applicative functors.
Safe HaskellSafe-Inferred
LanguageHaskell2010

Acme.Functors

Description

Types are great. Lifting them into some sort of applicative functor makes them even better. This module is an homage to our favorite applicatives, and to the semigroups with which they are instrinsically connected.

Synopsis

Lifted-but-why

data LiftedButWhy a Source #

LiftedButWhy is a boring functor that just has one value and no other structure or interesting properties.

Constructors

LiftedButWhy a

A value that has been lifted for some damned reason.

... Okay, to be honest, this one is nobody's favorite, but it is included here for completeness.

Instances

Instances details
Monad LiftedButWhy Source #
LiftedButWhy a >>= f = f a
Instance details

Defined in Acme.Functors

Functor LiftedButWhy Source # 
Instance details

Defined in Acme.Functors

Methods

fmap :: (a -> b) -> LiftedButWhy a -> LiftedButWhy b #

(<$) :: a -> LiftedButWhy b -> LiftedButWhy a #

Applicative LiftedButWhy Source #
pure = LiftedButWhy

LiftedButWhy f <*> LiftedButWhy a = LiftedButWhy (f a)
Instance details

Defined in Acme.Functors

Eq a => Eq (LiftedButWhy a) Source # 
Instance details

Defined in Acme.Functors

Show a => Show (LiftedButWhy a) Source # 
Instance details

Defined in Acme.Functors

Semigroup a => Semigroup (LiftedButWhy a) Source #
LiftedButWhy x <> LiftedButWhy y = LiftedButWhy (x <> y)
Instance details

Defined in Acme.Functors

Monoid a => Monoid (LiftedButWhy a) Source #
mempty = LiftedButWhy mempty
Instance details

Defined in Acme.Functors

Or-not

data OrNot a Source #

OrNot is somehow slightly more interesting than LiftedButWhy, even though it may actually contain less. Instead of a value, there might not be a value.

When you combine stuff with (<*>) or (<>), all of the values need to be present. If any of them are absent, the whole expression evaluates to Nope.

Constructors

ActuallyYes a

Some normal value.

Nope

Chuck Testa.

Instances

Instances details
Monad OrNot Source # 
Instance details

Defined in Acme.Functors

Methods

(>>=) :: OrNot a -> (a -> OrNot b) -> OrNot b #

(>>) :: OrNot a -> OrNot b -> OrNot b #

return :: a -> OrNot a #

Functor OrNot Source # 
Instance details

Defined in Acme.Functors

Methods

fmap :: (a -> b) -> OrNot a -> OrNot b #

(<$) :: a -> OrNot b -> OrNot a #

Applicative OrNot Source #

If you have a function f that might not actually be there, and a value a that might not actually be there, lifted application (<*>) gives you f a only if both of them are actually there.

pure = ActuallyYes

ActuallyYes f <*> ActuallyYes a = ActuallyYes (f a)
_             <*> _             = Nope
Instance details

Defined in Acme.Functors

Methods

pure :: a -> OrNot a #

(<*>) :: OrNot (a -> b) -> OrNot a -> OrNot b #

liftA2 :: (a -> b -> c) -> OrNot a -> OrNot b -> OrNot c #

(*>) :: OrNot a -> OrNot b -> OrNot b #

(<*) :: OrNot a -> OrNot b -> OrNot a #

Eq a => Eq (OrNot a) Source # 
Instance details

Defined in Acme.Functors

Methods

(==) :: OrNot a -> OrNot a -> Bool #

(/=) :: OrNot a -> OrNot a -> Bool #

Show a => Show (OrNot a) Source # 
Instance details

Defined in Acme.Functors

Methods

showsPrec :: Int -> OrNot a -> ShowS #

show :: OrNot a -> String #

showList :: [OrNot a] -> ShowS #

Semigroup a => Semigroup (OrNot a) Source #

If you have value a that may not actually be there, and another value a' that might not actually be there, the lifted semigroup operation (<>) gives you a <> a' only if both of them are actually there.

ActuallyYes a <> ActuallyYes a' = ActuallyYes (a <> a')
_             <> _              = Nope
Instance details

Defined in Acme.Functors

Methods

(<>) :: OrNot a -> OrNot a -> OrNot a #

sconcat :: NonEmpty (OrNot a) -> OrNot a #

stimes :: Integral b => b -> OrNot a -> OrNot a #

Monoid a => Monoid (OrNot a) Source #
mempty = ActuallyYes mempty
Instance details

Defined in Acme.Functors

Methods

mempty :: OrNot a Source #

Two

data Two a Source #

Two is two values. Yep. Just two values.

Constructors

Two 

Fields

Instances

Instances details
Functor Two Source # 
Instance details

Defined in Acme.Functors

Methods

fmap :: (a -> b) -> Two a -> Two b #

(<$) :: a -> Two b -> Two a #

Applicative Two Source #

If you have two functions f and g and two values a and a', then you can apply them with (<*>) to get two results f a and g a'.

pure a = Two a a

Two f g <*> Two a a' = Two (f a) (g a')
Instance details

Defined in Acme.Functors

Methods

pure :: a -> Two a #

(<*>) :: Two (a -> b) -> Two a -> Two b #

liftA2 :: (a -> b -> c) -> Two a -> Two b -> Two c #

(*>) :: Two a -> Two b -> Two b #

(<*) :: Two a -> Two b -> Two a #

Eq a => Eq (Two a) Source # 
Instance details

Defined in Acme.Functors

Methods

(==) :: Two a -> Two a -> Bool #

(/=) :: Two a -> Two a -> Bool #

Show a => Show (Two a) Source # 
Instance details

Defined in Acme.Functors

Methods

showsPrec :: Int -> Two a -> ShowS #

show :: Two a -> String #

showList :: [Two a] -> ShowS #

Semigroup a => Semigroup (Two a) Source #
Two x y <> Two x' y' = Two (x <> x') (y <> y')
Instance details

Defined in Acme.Functors

Methods

(<>) :: Two a -> Two a -> Two a #

sconcat :: NonEmpty (Two a) -> Two a #

stimes :: Integral b => b -> Two a -> Two a #

Monoid a => Monoid (Two a) Source #
mempty = Two mempty mempty
Instance details

Defined in Acme.Functors

Methods

mempty :: Two a Source #

Any-number-of

data AnyNumberOf a Source #

AnyNumberOf starts to get exciting. Any number of values you want. Zero ... one ... two ... three ... four ... five ... The possibilities are truly endless.

Constructors

OneAndMaybeMore a (AnyNumberOf a)

One value, and maybe even more after that!

ActuallyNone

Oh. Well this is less fun.

Instances

Instances details
Functor AnyNumberOf Source # 
Instance details

Defined in Acme.Functors

Methods

fmap :: (a -> b) -> AnyNumberOf a -> AnyNumberOf b #

(<$) :: a -> AnyNumberOf b -> AnyNumberOf a #

Applicative AnyNumberOf Source #

You can use this to apply any number of functions to any number of arguments.

pure a = OneAndMaybeMore a ActuallyNone

OneAndMaybeMore f fs <*> OneAndMaybeMore x xs =
    OneAndMaybeMore (f x) (fs <*> xs)
_ <*> _ = ActuallyNone

Example:

    ( (+ 1) ~~ (* 2) ~~ (+ 5) ~~       ActuallyNone )
<*> (    1  ~~    6  ~~    4  ~~ 37 ~~ ActuallyNone )
 =  (    2  ~~   12  ~~    9  ~~       ActuallyNone )

This example demonstrates how when there are more arguments than functions, any excess arguments (in this case, the 37) are ignored.

Instance details

Defined in Acme.Functors

Methods

pure :: a -> AnyNumberOf a #

(<*>) :: AnyNumberOf (a -> b) -> AnyNumberOf a -> AnyNumberOf b #

liftA2 :: (a -> b -> c) -> AnyNumberOf a -> AnyNumberOf b -> AnyNumberOf c #

(*>) :: AnyNumberOf a -> AnyNumberOf b -> AnyNumberOf b #

(<*) :: AnyNumberOf a -> AnyNumberOf b -> AnyNumberOf a #

Eq a => Eq (AnyNumberOf a) Source # 
Instance details

Defined in Acme.Functors

Show a => Show (AnyNumberOf a) Source # 
Instance details

Defined in Acme.Functors

Semigroup a => Semigroup (AnyNumberOf a) Source #

The operation of combining some number of a with some other number of a is sometimes referred to as zipping.

OneAndMaybeMore x xs <> OneAndMaybeMore y ys =
    OneAndMaybeMore (x <> y) (xs <> ys)
_ <> _ = ActuallyNone
Instance details

Defined in Acme.Functors

Monoid a => Monoid (AnyNumberOf a) Source #
mempty = mempty ~~ mempty
Instance details

Defined in Acme.Functors

(~~) :: a -> AnyNumberOf a -> AnyNumberOf a infixr 5 Source #

Alias for OneAndMaybeMore which provides some brevity.

One-or-more

data OneOrMore a Source #

OneOrMore is more restrictive than AnyNumberOf, yet somehow actually more interesting, because it excludes that dull situation where there aren't any values at all.

Constructors

OneOrMore 

Fields

Instances

Instances details
Functor OneOrMore Source # 
Instance details

Defined in Acme.Functors

Methods

fmap :: (a -> b) -> OneOrMore a -> OneOrMore b #

(<$) :: a -> OneOrMore b -> OneOrMore a #

Applicative OneOrMore Source #
pure a = OneOrMore a ActuallyNone

OneOrMore f fs <*> OneOrMore x xs = OneOrMore (f x) (fs <*> xs)
Instance details

Defined in Acme.Functors

Methods

pure :: a -> OneOrMore a #

(<*>) :: OneOrMore (a -> b) -> OneOrMore a -> OneOrMore b #

liftA2 :: (a -> b -> c) -> OneOrMore a -> OneOrMore b -> OneOrMore c #

(*>) :: OneOrMore a -> OneOrMore b -> OneOrMore b #

(<*) :: OneOrMore a -> OneOrMore b -> OneOrMore a #

Eq a => Eq (OneOrMore a) Source # 
Instance details

Defined in Acme.Functors

Methods

(==) :: OneOrMore a -> OneOrMore a -> Bool #

(/=) :: OneOrMore a -> OneOrMore a -> Bool #

Show a => Show (OneOrMore a) Source # 
Instance details

Defined in Acme.Functors

Semigroup a => Semigroup (OneOrMore a) Source #
OneOrMore a more <> OneOrMore a' more' =
    OneOrMore a (more <> OneAndMaybeMore a' more')
Instance details

Defined in Acme.Functors

Methods

(<>) :: OneOrMore a -> OneOrMore a -> OneOrMore a #

sconcat :: NonEmpty (OneOrMore a) -> OneOrMore a #

stimes :: Integral b => b -> OneOrMore a -> OneOrMore a #

Monoid a => Monoid (OneOrMore a) Source #
mempty = OneOrMore mempty ActuallyNone
Instance details

Defined in Acme.Functors

Methods

mempty :: OneOrMore a Source #

Also-extra-thing

data Also extraThing a Source #

Also extraThing is a functor in which each value has an extraThing of some other type that tags along with it.

Constructors

Also 

Fields

Instances

Instances details
Functor (Also extraThing) Source # 
Instance details

Defined in Acme.Functors

Methods

fmap :: (a -> b) -> Also extraThing a -> Also extraThing b #

(<$) :: a -> Also extraThing b -> Also extraThing a #

Monoid extraThing => Applicative (Also extraThing) Source #

Dragging the extraThing along can be a bit of a burden. It prevents Also extraThing from being an applicative functor — unless the extraThing can pull its weight by bringing a monoid to the table.

pure = (`Also` mempty)

(f `Also` extra1) <*> (a `Also` extra2) = f a
                                          `Also` (extra1 <> extra2)
Instance details

Defined in Acme.Functors

Methods

pure :: a -> Also extraThing a #

(<*>) :: Also extraThing (a -> b) -> Also extraThing a -> Also extraThing b #

liftA2 :: (a -> b -> c) -> Also extraThing a -> Also extraThing b -> Also extraThing c #

(*>) :: Also extraThing a -> Also extraThing b -> Also extraThing b #

(<*) :: Also extraThing a -> Also extraThing b -> Also extraThing a #

(Eq a, Eq extraThing) => Eq (Also extraThing a) Source # 
Instance details

Defined in Acme.Functors

Methods

(==) :: Also extraThing a -> Also extraThing a -> Bool #

(/=) :: Also extraThing a -> Also extraThing a -> Bool #

(Show a, Show extraThing) => Show (Also extraThing a) Source # 
Instance details

Defined in Acme.Functors

Methods

showsPrec :: Int -> Also extraThing a -> ShowS #

show :: Also extraThing a -> String #

showList :: [Also extraThing a] -> ShowS #

(Semigroup extraThing, Semigroup a) => Semigroup (Also extraThing a) Source #
(a `Also` extra1) <> (a' `Also` extra2) = (a <> a')
                                          `Also` (extra1 <> extra2)
Instance details

Defined in Acme.Functors

Methods

(<>) :: Also extraThing a -> Also extraThing a -> Also extraThing a #

sconcat :: NonEmpty (Also extraThing a) -> Also extraThing a #

stimes :: Integral b => b -> Also extraThing a -> Also extraThing a #

(Monoid extraThing, Monoid a) => Monoid (Also extraThing a) Source #
mempty = Also mempty mempty
Instance details

Defined in Acme.Functors

Methods

mempty :: Also extraThing a Source #

Or-instead-other-thing

data OrInstead otherThing a Source #

OrInstead otherThing is a functor in which, instead of having a value, can actually just have some totally unrelated otherThing instead.

When you combine stuff with (<*>) or (<>), all of the values need to be present. If any of them are the otherThing instead, then the whole expression evaluates to the combination of the otherThings.

Constructors

NotInstead a

A normal value.

Instead otherThing

Some totally unrelated other thing.

Instances

Instances details
Functor (OrInstead otherThing) Source # 
Instance details

Defined in Acme.Functors

Methods

fmap :: (a -> b) -> OrInstead otherThing a -> OrInstead otherThing b #

(<$) :: a -> OrInstead otherThing b -> OrInstead otherThing a #

Semigroup otherThing => Applicative (OrInstead otherThing) Source #

The possibility of having an otherThing obstructs this functor's ability to be applicative, much like the extra thing in Also extraThing does. In this case, since we do not need an empty value for the otherThing, it needs only a semigroup to be in compliance.

pure = NotInstead

NotInstead f   <*> NotInstead a   = NotInstead (f a)
Instead other1 <*> Instead other2 = Instead (other1 <> other2)
Instead other  <*> _              = Instead other
_              <*> Instead other  = Instead other
Instance details

Defined in Acme.Functors

Methods

pure :: a -> OrInstead otherThing a #

(<*>) :: OrInstead otherThing (a -> b) -> OrInstead otherThing a -> OrInstead otherThing b #

liftA2 :: (a -> b -> c) -> OrInstead otherThing a -> OrInstead otherThing b -> OrInstead otherThing c #

(*>) :: OrInstead otherThing a -> OrInstead otherThing b -> OrInstead otherThing b #

(<*) :: OrInstead otherThing a -> OrInstead otherThing b -> OrInstead otherThing a #

(Eq a, Eq otherThing) => Eq (OrInstead otherThing a) Source # 
Instance details

Defined in Acme.Functors

Methods

(==) :: OrInstead otherThing a -> OrInstead otherThing a -> Bool #

(/=) :: OrInstead otherThing a -> OrInstead otherThing a -> Bool #

(Show a, Show otherThing) => Show (OrInstead otherThing a) Source # 
Instance details

Defined in Acme.Functors

Methods

showsPrec :: Int -> OrInstead otherThing a -> ShowS #

show :: OrInstead otherThing a -> String #

showList :: [OrInstead otherThing a] -> ShowS #

(Semigroup otherThing, Semigroup a) => Semigroup (OrInstead otherThing a) Source #
NotInstead a   <> NotInstead a'  = NotInstead (a <> a')
Instead other1 <> Instead other2 = Instead (other1 <> other2)
Instead other  <> _              = Instead other
_              <> Instead other  = Instead other
Instance details

Defined in Acme.Functors

Methods

(<>) :: OrInstead otherThing a -> OrInstead otherThing a -> OrInstead otherThing a #

sconcat :: NonEmpty (OrInstead otherThing a) -> OrInstead otherThing a #

stimes :: Integral b => b -> OrInstead otherThing a -> OrInstead otherThing a #

(Semigroup otherThing, Monoid a) => Monoid (OrInstead otherThing a) Source # 
Instance details

Defined in Acme.Functors

Methods

mempty :: OrInstead otherThing a Source #

Or-instead-other-thing ("first" variant)

data OrInsteadFirst otherThing a Source #

OrInsteadFirst otherThing looks a lot like OrInstead otherThing, but it manages to always be an applicative functor — and even a monad too — by handling the otherThings a bit more hamfistedly.

When you combine stuff with (<*>) or (<>), all of the values need to be present. If any of them are the otherThing instead, then the whole expression evaluates to the first otherThing encountered, ignoring any additional otherThings that may subsequently pop up.

Constructors

NotInsteadFirst a

A normal value.

InsteadFirst otherThing

Some totally unrelated other thing.

Instances

Instances details
Monad (OrInsteadFirst otherThing) Source #
InsteadFirst other >>= _ = InsteadFirst other
NotInsteadFirst a  >>= f = f a
Instance details

Defined in Acme.Functors

Methods

(>>=) :: OrInsteadFirst otherThing a -> (a -> OrInsteadFirst otherThing b) -> OrInsteadFirst otherThing b #

(>>) :: OrInsteadFirst otherThing a -> OrInsteadFirst otherThing b -> OrInsteadFirst otherThing b #

return :: a -> OrInsteadFirst otherThing a #

Functor (OrInsteadFirst otherThing) Source # 
Instance details

Defined in Acme.Functors

Methods

fmap :: (a -> b) -> OrInsteadFirst otherThing a -> OrInsteadFirst otherThing b #

(<$) :: a -> OrInsteadFirst otherThing b -> OrInsteadFirst otherThing a #

Applicative (OrInsteadFirst otherThing) Source #
pure = NotInsteadFirst

NotInsteadFirst f  <*> NotInsteadFirst a  = NotInsteadFirst (f a)
InsteadFirst other <*> _                  = InsteadFirst other
_                  <*> InsteadFirst other = InsteadFirst other
Instance details

Defined in Acme.Functors

Methods

pure :: a -> OrInsteadFirst otherThing a #

(<*>) :: OrInsteadFirst otherThing (a -> b) -> OrInsteadFirst otherThing a -> OrInsteadFirst otherThing b #

liftA2 :: (a -> b -> c) -> OrInsteadFirst otherThing a -> OrInsteadFirst otherThing b -> OrInsteadFirst otherThing c #

(*>) :: OrInsteadFirst otherThing a -> OrInsteadFirst otherThing b -> OrInsteadFirst otherThing b #

(<*) :: OrInsteadFirst otherThing a -> OrInsteadFirst otherThing b -> OrInsteadFirst otherThing a #

(Eq a, Eq otherThing) => Eq (OrInsteadFirst otherThing a) Source # 
Instance details

Defined in Acme.Functors

Methods

(==) :: OrInsteadFirst otherThing a -> OrInsteadFirst otherThing a -> Bool #

(/=) :: OrInsteadFirst otherThing a -> OrInsteadFirst otherThing a -> Bool #

(Show a, Show otherThing) => Show (OrInsteadFirst otherThing a) Source # 
Instance details

Defined in Acme.Functors

Methods

showsPrec :: Int -> OrInsteadFirst otherThing a -> ShowS #

show :: OrInsteadFirst otherThing a -> String #

showList :: [OrInsteadFirst otherThing a] -> ShowS #

(Semigroup otherThing, Semigroup a) => Semigroup (OrInsteadFirst otherThing a) Source #
NotInsteadFirst a  <> NotInsteadFirst a' = NotInsteadFirst (a <> a')
InsteadFirst other <> _                  = InsteadFirst other
_                  <> InsteadFirst other = InsteadFirst other
Instance details

Defined in Acme.Functors

Methods

(<>) :: OrInsteadFirst otherThing a -> OrInsteadFirst otherThing a -> OrInsteadFirst otherThing a #

sconcat :: NonEmpty (OrInsteadFirst otherThing a) -> OrInsteadFirst otherThing a #

stimes :: Integral b => b -> OrInsteadFirst otherThing a -> OrInsteadFirst otherThing a #

(Semigroup otherThing, Monoid a) => Monoid (OrInsteadFirst otherThing a) Source #
mempty = NotInsteadFirst mempty
Instance details

Defined in Acme.Functors

Methods

mempty :: OrInsteadFirst otherThing a Source #

Determined-by-parameter

data DeterminedBy parameter a Source #

DeterminedBy parameter is a value that... well, we're not really sure what it is. We'll find out once a parameter is provided.

The mechanism for deciding how the value is determined from the parameter is opaque; all you can do is test it with different parameters and see what results. There aren't even Eq or Show instances, which is annoying.

Constructors

Determination ((->) parameter a) 

Instances

Instances details
Monad (DeterminedBy parameter) Source #
Determination fa >>= ff =
    Determination (\x -> let Determination f = ff (fa x) in f x)
Instance details

Defined in Acme.Functors

Methods

(>>=) :: DeterminedBy parameter a -> (a -> DeterminedBy parameter b) -> DeterminedBy parameter b #

(>>) :: DeterminedBy parameter a -> DeterminedBy parameter b -> DeterminedBy parameter b #

return :: a -> DeterminedBy parameter a #

Functor (DeterminedBy parameter) Source # 
Instance details

Defined in Acme.Functors

Methods

fmap :: (a -> b) -> DeterminedBy parameter a -> DeterminedBy parameter b #

(<$) :: a -> DeterminedBy parameter b -> DeterminedBy parameter a #

Applicative (DeterminedBy parameter) Source #
pure a = Determination (\_ -> a)

Determination f <*> Determination a = Determination (\x -> f x (a x))
Instance details

Defined in Acme.Functors

Methods

pure :: a -> DeterminedBy parameter a #

(<*>) :: DeterminedBy parameter (a -> b) -> DeterminedBy parameter a -> DeterminedBy parameter b #

liftA2 :: (a -> b -> c) -> DeterminedBy parameter a -> DeterminedBy parameter b -> DeterminedBy parameter c #

(*>) :: DeterminedBy parameter a -> DeterminedBy parameter b -> DeterminedBy parameter b #

(<*) :: DeterminedBy parameter a -> DeterminedBy parameter b -> DeterminedBy parameter a #

Semigroup a => Semigroup (DeterminedBy parameter a) Source #
Determination f <> Determination g = Determination (\x -> f x <> g x)
Instance details

Defined in Acme.Functors

Methods

(<>) :: DeterminedBy parameter a -> DeterminedBy parameter a -> DeterminedBy parameter a #

sconcat :: NonEmpty (DeterminedBy parameter a) -> DeterminedBy parameter a #

stimes :: Integral b => b -> DeterminedBy parameter a -> DeterminedBy parameter a #

Monoid a => Monoid (DeterminedBy parameter a) Source #
mempty = Determination (\_ -> mempty)
Instance details

Defined in Acme.Functors

Methods

mempty :: DeterminedBy parameter a Source #