acme-functors-0.1.0.0: The best applicative functors.

Safe HaskellSafe
LanguageHaskell2010

Acme.Functors

Contents

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

Monad LiftedButWhy Source #
LiftedButWhy a >>= f = f a
Functor LiftedButWhy Source # 

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)
Eq a => Eq (LiftedButWhy a) Source # 
Show a => Show (LiftedButWhy a) Source # 
Semigroup a => Semigroup (LiftedButWhy a) Source #
LiftedButWhy x <> LiftedButWhy y = LiftedButWhy (x <> y)
Monoid a => Monoid (LiftedButWhy a) Source #
mempty = LiftedButWhy mempty

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

Monad OrNot Source # 

Methods

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

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

return :: a -> OrNot a #

fail :: String -> OrNot a #

Functor OrNot Source # 

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

Methods

pure :: a -> OrNot a #

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

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

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

Eq a => Eq (OrNot a) Source # 

Methods

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

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

Show a => Show (OrNot a) Source # 

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

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

Methods

mempty :: OrNot a Source #

Two

data Two a Source #

Two is two values. Yep. Just two values.

Constructors

Two 

Fields

Instances

Functor Two Source # 

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')

Methods

pure :: a -> Two a #

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

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

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

Eq a => Eq (Two a) Source # 

Methods

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

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

Show a => Show (Two a) Source # 

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')

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

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

Functor AnyNumberOf Source # 

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 )
 =  (    7  ~~   12  ~~    9  ~~       ActuallyNone )

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

Eq a => Eq (AnyNumberOf a) Source # 
Show a => Show (AnyNumberOf a) Source # 
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
Monoid a => Monoid (AnyNumberOf a) Source #
mempty = mempty ~~ mempty

(~~) :: 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

Functor OneOrMore Source # 

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)

Methods

pure :: a -> OneOrMore a #

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

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

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

Eq a => Eq (OneOrMore a) Source # 

Methods

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

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

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

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

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

Functor (Also extraThing) Source # 

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)

Methods

pure :: a -> Also extraThing a #

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

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

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

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

Methods

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

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

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

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)

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

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

Some normal value.

Instead otherThing

Some totally unrelated other thing.

Instances

Functor (OrInstead otherThing) Source # 

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

Methods

pure :: a -> OrInstead otherThing a #

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

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

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

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

Methods

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

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

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

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

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 # 

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

Some normal value.

InsteadFirst otherThing

Some totally unrelated other thing.

Instances

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

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 #

fail :: String -> OrInsteadFirst otherThing a #

Functor (OrInsteadFirst otherThing) Source # 

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

Methods

pure :: a -> OrInsteadFirst otherThing a #

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

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

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

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

Methods

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

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

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

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

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

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

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

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 #

fail :: String -> DeterminedBy parameter a #

Functor (DeterminedBy parameter) Source # 

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))

Methods

pure :: a -> DeterminedBy parameter a #

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

(*>) :: 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)

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)

Methods

mempty :: DeterminedBy parameter a Source #