smash-0.1.0.0: Smash products - like 'These', but with a unit!

Copyright(c) 2020 Emily Pillmore
LicenseBSD-3-Clause
MaintainerEmily Pillmore <emilypi@cohomolo.gy>
StabilityExperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

Data.Can

Contents

Description

This module contains the definition for the Can datatype. In practice, this type is isomorphic to Maybe These - the type with two possibly non-exclusive values and an empty case.

Synopsis

Datatypes

Categorically, the Can datatype represents the pointed product in the category Hask* of pointed Hask types. The category Hask* consists of Hask types affixed with a dedicated base point of an object along with the object. In Hask*, this is equivalent to `1 + a`, or 'Maybe a' in Hask. Hence, the product is `(1 + a) * (1 + b) ~ 1 + a + b + a*b`, or `Maybe (Either (Either a b) (a,b))` in Hask. Pictorially, you can visualize this as:

Can:
        a
        |
Non +---+---+ (a,b)
        |
        b

The fact that we can think about Can as your average product gives us some reasoning power about how this thing will be able to interact with the coproduct in Hask*, called Wedge. Namely, facts about currying 'Can a b -> c ~ a -> b -> c' and distributivity over Wedge along with other facts about its associativity, commutativity, and any other analogy with `(,)` that you can think of.

data Can a b Source #

The Can data type represents values with two non-exclusive possibilities, as well as an empty case. This is a product of pointed types - i.e. of Maybe values. The result is a type, 'Can a b', which is isomorphic to 'Maybe (These a b)'.

Constructors

Non 
One a 
Eno b 
Two a b 
Instances
Bitraversable Can Source # 
Instance details

Defined in Data.Can

Methods

bitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> Can a b -> f (Can c d) #

Bifoldable Can Source # 
Instance details

Defined in Data.Can

Methods

bifold :: Monoid m => Can m m -> m #

bifoldMap :: Monoid m => (a -> m) -> (b -> m) -> Can a b -> m #

bifoldr :: (a -> c -> c) -> (b -> c -> c) -> c -> Can a b -> c #

bifoldl :: (c -> a -> c) -> (c -> b -> c) -> c -> Can a b -> c #

Bifunctor Can Source # 
Instance details

Defined in Data.Can

Methods

bimap :: (a -> b) -> (c -> d) -> Can a c -> Can b d #

first :: (a -> b) -> Can a c -> Can b c #

second :: (b -> c) -> Can a b -> Can a c #

Semigroup a => Monad (Can a) Source # 
Instance details

Defined in Data.Can

Methods

(>>=) :: Can a a0 -> (a0 -> Can a b) -> Can a b #

(>>) :: Can a a0 -> Can a b -> Can a b #

return :: a0 -> Can a a0 #

fail :: String -> Can a a0 #

Functor (Can a) Source # 
Instance details

Defined in Data.Can

Methods

fmap :: (a0 -> b) -> Can a a0 -> Can a b #

(<$) :: a0 -> Can a b -> Can a a0 #

Semigroup a => Applicative (Can a) Source # 
Instance details

Defined in Data.Can

Methods

pure :: a0 -> Can a a0 #

(<*>) :: Can a (a0 -> b) -> Can a a0 -> Can a b #

liftA2 :: (a0 -> b -> c) -> Can a a0 -> Can a b -> Can a c #

(*>) :: Can a a0 -> Can a b -> Can a b #

(<*) :: Can a a0 -> Can a b -> Can a a0 #

Foldable (Can a) Source # 
Instance details

Defined in Data.Can

Methods

fold :: Monoid m => Can a m -> m #

foldMap :: Monoid m => (a0 -> m) -> Can a a0 -> m #

foldr :: (a0 -> b -> b) -> b -> Can a a0 -> b #

foldr' :: (a0 -> b -> b) -> b -> Can a a0 -> b #

foldl :: (b -> a0 -> b) -> b -> Can a a0 -> b #

foldl' :: (b -> a0 -> b) -> b -> Can a a0 -> b #

foldr1 :: (a0 -> a0 -> a0) -> Can a a0 -> a0 #

foldl1 :: (a0 -> a0 -> a0) -> Can a a0 -> a0 #

toList :: Can a a0 -> [a0] #

null :: Can a a0 -> Bool #

length :: Can a a0 -> Int #

elem :: Eq a0 => a0 -> Can a a0 -> Bool #

maximum :: Ord a0 => Can a a0 -> a0 #

minimum :: Ord a0 => Can a a0 -> a0 #

sum :: Num a0 => Can a a0 -> a0 #

product :: Num a0 => Can a a0 -> a0 #

Traversable (Can a) Source # 
Instance details

Defined in Data.Can

Methods

traverse :: Applicative f => (a0 -> f b) -> Can a a0 -> f (Can a b) #

sequenceA :: Applicative f => Can a (f a0) -> f (Can a a0) #

mapM :: Monad m => (a0 -> m b) -> Can a a0 -> m (Can a b) #

sequence :: Monad m => Can a (m a0) -> m (Can a a0) #

Generic1 (Can a :: Type -> Type) Source # 
Instance details

Defined in Data.Can

Associated Types

type Rep1 (Can a) :: k -> Type #

Methods

from1 :: Can a a0 -> Rep1 (Can a) a0 #

to1 :: Rep1 (Can a) a0 -> Can a a0 #

(Eq a, Eq b) => Eq (Can a b) Source # 
Instance details

Defined in Data.Can

Methods

(==) :: Can a b -> Can a b -> Bool #

(/=) :: Can a b -> Can a b -> Bool #

(Data a, Data b) => Data (Can a b) Source # 
Instance details

Defined in Data.Can

Methods

gfoldl :: (forall d b0. Data d => c (d -> b0) -> d -> c b0) -> (forall g. g -> c g) -> Can a b -> c (Can a b) #

gunfold :: (forall b0 r. Data b0 => c (b0 -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Can a b) #

toConstr :: Can a b -> Constr #

dataTypeOf :: Can a b -> DataType #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Can a b)) #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Can a b)) #

gmapT :: (forall b0. Data b0 => b0 -> b0) -> Can a b -> Can a b #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Can a b -> r #

gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Can a b -> r #

gmapQ :: (forall d. Data d => d -> u) -> Can a b -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Can a b -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Can a b -> m (Can a b) #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Can a b -> m (Can a b) #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Can a b -> m (Can a b) #

(Ord a, Ord b) => Ord (Can a b) Source # 
Instance details

Defined in Data.Can

Methods

compare :: Can a b -> Can a b -> Ordering #

(<) :: Can a b -> Can a b -> Bool #

(<=) :: Can a b -> Can a b -> Bool #

(>) :: Can a b -> Can a b -> Bool #

(>=) :: Can a b -> Can a b -> Bool #

max :: Can a b -> Can a b -> Can a b #

min :: Can a b -> Can a b -> Can a b #

(Read a, Read b) => Read (Can a b) Source # 
Instance details

Defined in Data.Can

Methods

readsPrec :: Int -> ReadS (Can a b) #

readList :: ReadS [Can a b] #

readPrec :: ReadPrec (Can a b) #

readListPrec :: ReadPrec [Can a b] #

(Show a, Show b) => Show (Can a b) Source # 
Instance details

Defined in Data.Can

Methods

showsPrec :: Int -> Can a b -> ShowS #

show :: Can a b -> String #

showList :: [Can a b] -> ShowS #

Generic (Can a b) Source # 
Instance details

Defined in Data.Can

Associated Types

type Rep (Can a b) :: Type -> Type #

Methods

from :: Can a b -> Rep (Can a b) x #

to :: Rep (Can a b) x -> Can a b #

(Semigroup a, Semigroup b) => Semigroup (Can a b) Source # 
Instance details

Defined in Data.Can

Methods

(<>) :: Can a b -> Can a b -> Can a b #

sconcat :: NonEmpty (Can a b) -> Can a b #

stimes :: Integral b0 => b0 -> Can a b -> Can a b #

(Semigroup a, Semigroup b) => Monoid (Can a b) Source # 
Instance details

Defined in Data.Can

Methods

mempty :: Can a b #

mappend :: Can a b -> Can a b -> Can a b #

mconcat :: [Can a b] -> Can a b #

(Hashable a, Hashable b) => Hashable (Can a b) Source # 
Instance details

Defined in Data.Can

Methods

hashWithSalt :: Int -> Can a b -> Int

hash :: Can a b -> Int

type Rep1 (Can a :: Type -> Type) Source # 
Instance details

Defined in Data.Can

type Rep (Can a b) Source # 
Instance details

Defined in Data.Can

Combinators

canFst :: Can a b -> Maybe a Source #

Project the left value of a Can datatype. This is analogous to fst for '(,)'.

canSnd :: Can a b -> Maybe b Source #

Project the right value of a Can datatype. This is analogous to snd for '(,)'.

isOne :: Can a b -> Bool Source #

Detect if a Can is a One case.

isEno :: Can a b -> Bool Source #

Detect if a Can is a Eno case.

isTwo :: Can a b -> Bool Source #

Detect if a Can is a Two case.

isNon :: Can a b -> Bool Source #

Detect if a Can is a Non case.

Eliminators

can Source #

Arguments

:: c

default value to supply for the Non case

-> (a -> c)

eliminator for the One case

-> (b -> c)

eliminator for the Eno case

-> (a -> b -> c)

eliminator for the Two case

-> Can a b 
-> c 

Case elimination for the Can datatype

Folding

foldOnes :: Foldable f => (a -> m -> m) -> m -> f (Can a b) -> m Source #

Fold over the One cases of a Foldable of Cans by some accumulating function.

foldEnos :: Foldable f => (b -> m -> m) -> m -> f (Can a b) -> m Source #

Fold over the Eno cases of a Foldable of Cans by some accumulating function.

foldTwos :: Foldable f => (a -> b -> m -> m) -> m -> f (Can a b) -> m Source #

Fold over the Two cases of a Foldable of Cans by some accumulating function.

gatherCans :: Can [a] [b] -> [Can a b] Source #

Gather a Can of two lists and produce a list of Can values, mapping the Non case to the empty list, One' case to a list of Ones, the Eno case to a list of Enos, or zipping Two along both lists.

Filtering

ones :: Foldable f => f (Can a b) -> [a] Source #

Given a Foldable of Cans, collect the values of the One cases, if any.

enos :: Foldable f => f (Can a b) -> [b] Source #

Given a Foldable of Cans, collect the values of the Eno cases, if any.

twos :: Foldable f => f (Can a b) -> [(a, b)] Source #

Given a Foldable of Cans, collect the values of the Two cases, if any.

filterOnes :: Foldable f => f (Can a b) -> [Can a b] Source #

Filter the One cases of a Foldable of Can values.

filterEnos :: Foldable f => f (Can a b) -> [Can a b] Source #

Filter the Eno cases of a Foldable of Can values.

filterTwos :: Foldable f => f (Can a b) -> [Can a b] Source #

Filter the Two cases of a Foldable of Can values.

filterNons :: Foldable f => f (Can a b) -> [Can a b] Source #

Filter the Non cases of a Foldable of Can values.

Curry & Uncurry

canCurry :: (Can a b -> Maybe c) -> Maybe a -> Maybe b -> Maybe c Source #

Curry a function from a Can to a Maybe value, resulting in a function of curried Maybe values. This is analogous to currying for '(->)'.

canUncurry :: (Maybe a -> Maybe b -> Maybe c) -> Can a b -> Maybe c Source #

Uncurry a function from a Can to a Maybe value, resulting in a function of curried Maybe values. This is analogous to uncurrying for '(->)'.

Partitioning

partitionCans :: forall f t a b. (Foldable t, Alternative f) => t (Can a b) -> (f a, f b) Source #

Given a Foldable of Cans, partition it into a tuple of alternatives their parts.

partitionAll :: Foldable f => f (Can a b) -> ([a], [b], [(a, b)]) Source #

Partition a list of Can values into a triple of lists of all of their constituent parts

partitionEithers :: Foldable f => f (Either a b) -> Can [a] [b] Source #

Partition a list of Either values, separating them into a Can value of lists of left and right values, or Non in the case of an empty list.

mapCans :: forall f t a b c. (Alternative f, Traversable t) => (a -> Can b c) -> t a -> (f b, f c) Source #

Partition a structure by mapping its contents into Cans, and folding over '(|)'.

Distributivity

distributeCan :: Can (a, b) c -> (Can a c, Can b c) Source #

Distribute a Can value over a product.

codistributeCan :: Either (Can a c) (Can b c) -> Can (Either a b) c Source #

Codistribute a coproduct over a Can value.

Associativity

reassocLR :: Can (Can a b) c -> Can a (Can b c) Source #

Re-associate a Can of cans from left to right.

reassocRL :: Can a (Can b c) -> Can (Can a b) c Source #

Re-associate a Can of cans from right to left.

Symmetry

swapCan :: Can a b -> Can b a Source #

Swap the positions of values in a Can.