Copyright | (c) 2020 Emily Pillmore |
---|---|

License | BSD-3-Clause |

Maintainer | Emily Pillmore <emilypi@cohomolo.gy> |

Stability | Experimental |

Portability | CPP, RankNTypes, TypeApplications |

Safe Haskell | Safe |

Language | Haskell2010 |

This module contains the definition for the `Smash`

datatype. In
practice, this type is isomorphic to 'Maybe (a,b)' - the type with
two possibly non-exclusive values and an empty case.

## Synopsis

- data Smash a b
- toSmash :: Maybe (a, b) -> Smash a b
- fromSmash :: Smash a b -> Maybe (a, b)
- smashFst :: Smash a b -> Maybe a
- smashSnd :: Smash a b -> Maybe b
- quotSmash :: Can a b -> Smash a b
- hulkSmash :: a -> b -> Wedge a b -> Smash a b
- isSmash :: Smash a b -> Bool
- isNada :: Smash a b -> Bool
- smash :: c -> (a -> b -> c) -> Smash a b -> c
- smashes :: Foldable f => f (Smash a b) -> [(a, b)]
- filterNadas :: Foldable f => f (Smash a b) -> [Smash a b]
- foldSmashes :: Foldable f => (a -> b -> m -> m) -> m -> f (Smash a b) -> m
- gatherSmashes :: Smash [a] [b] -> [Smash a b]
- partitionSmashes :: forall f t a b. (Foldable t, Alternative f) => t (Smash a b) -> (f a, f b)
- mapSmashes :: forall f t a b c. (Alternative f, Traversable t) => (a -> Smash b c) -> t a -> (f b, f c)
- smashCurry :: (Smash a b -> Maybe c) -> Maybe a -> Maybe b -> Maybe c
- smashUncurry :: (Maybe a -> Maybe b -> Maybe c) -> Smash a b -> Maybe c
- distributeSmash :: Smash (Wedge a b) c -> Wedge (Smash a c) (Smash b c)
- undistributeSmash :: Wedge (Smash a c) (Smash b c) -> Smash (Wedge a b) c
- pairSmash :: Smash (a, b) c -> (Smash a c, Smash b c)
- unpairSmash :: (Smash a c, Smash b c) -> Smash (a, b) c
- pairSmashCan :: Smash (Can a b) c -> Can (Smash a c) (Smash b c)
- unpairSmashCan :: Can (Smash a c) (Smash b c) -> Smash (Can a b) c
- reassocLR :: Smash (Smash a b) c -> Smash a (Smash b c)
- reassocRL :: Smash a (Smash b c) -> Smash (Smash a b) c
- swapSmash :: Smash a b -> Smash b a

# Datatypes

Categorically, the `Smash`

datatype represents a special type of product, a
smash product, in the category Hask*
of pointed Hask types. The category Hask* consists of Hask types affixed with
a dedicated base point - i.e. all objects look like 'Maybe a'. The smash product is a symmetric, monoidal tensor in Hask* that plays
nicely with the product, `Can`

, and coproduct, `Wedge`

. Pictorially,
these datatypes look like this:

`Can`

: a | Non +---+---+ (a,b) | b`Wedge`

: a | Nowhere +-------+ | b`Smash`

: Nada +--------+ (a,b)

The fact that smash products form a closed, symmetric monoidal tensor for Hask*
means that we can speak in terms of the language of linear logic for this category.
Namely, we can understand how `Smash`

, `Wedge`

, and `Can`

interact. `Can`

and `Wedge`

distribute nicely over each other, and `Smash`

distributes well over `Wedge`

, but
is only semi-distributable over `Wedge'`

s linear counterpart, which is left
out of the api. In this library, we focus on the fragment of this pointed linear logic
that makes sense to use, and that will be useful to us as Haskell developers.

The `Smash`

data type represents A value which has either an
empty case, or two values. The result is a type, 'Smash a b', which is
isomorphic to 'Maybe (a,b)'.

Categorically, the smash product (the quotient of a pointed product by
a wedge sum) has interesting properties. It forms a closed
symmetric-monoidal tensor in the category Hask* of pointed haskell
types (i.e. `Maybe`

values).

## Instances

Bitraversable Smash Source # | |

Defined in Data.Smash bitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> Smash a b -> f (Smash c d) # | |

Bifoldable Smash Source # | |

Bifunctor Smash Source # | |

Monoid a => Monad (Smash a) Source # | |

Functor (Smash a) Source # | |

Monoid a => Applicative (Smash a) Source # | |

Generic1 (Smash a :: Type -> Type) Source # | |

(Eq a, Eq b) => Eq (Smash a b) Source # | |

(Data a, Data b) => Data (Smash a b) Source # | |

Defined in Data.Smash gfoldl :: (forall d b0. Data d => c (d -> b0) -> d -> c b0) -> (forall g. g -> c g) -> Smash a b -> c (Smash a b) # gunfold :: (forall b0 r. Data b0 => c (b0 -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Smash a b) # toConstr :: Smash a b -> Constr # dataTypeOf :: Smash a b -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Smash a b)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Smash a b)) # gmapT :: (forall b0. Data b0 => b0 -> b0) -> Smash a b -> Smash a b # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Smash a b -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Smash a b -> r # gmapQ :: (forall d. Data d => d -> u) -> Smash a b -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Smash a b -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Smash a b -> m (Smash a b) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Smash a b -> m (Smash a b) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Smash a b -> m (Smash a b) # | |

(Ord a, Ord b) => Ord (Smash a b) Source # | |

Defined in Data.Smash | |

(Read a, Read b) => Read (Smash a b) Source # | |

(Show a, Show b) => Show (Smash a b) Source # | |

Generic (Smash a b) Source # | |

(Semigroup a, Semigroup b) => Semigroup (Smash a b) Source # | |

(Semigroup a, Semigroup b) => Monoid (Smash a b) Source # | |

(Binary a, Binary b) => Binary (Smash a b) Source # | |

(NFData a, NFData b) => NFData (Smash a b) Source # | |

Defined in Data.Smash | |

(Hashable a, Hashable b) => Hashable (Smash a b) Source # | |

Defined in Data.Smash | |

type Rep1 (Smash a :: Type -> Type) Source # | |

Defined in Data.Smash type Rep1 (Smash a :: Type -> Type) = D1 (MetaData "Smash" "Data.Smash" "smash-0.1.1.0-8T61bCPN60yH3RLoZzb2ua" False) (C1 (MetaCons "Nada" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "Smash" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 a) :*: S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) Par1)) | |

type Rep (Smash a b) Source # | |

Defined in Data.Smash type Rep (Smash a b) = D1 (MetaData "Smash" "Data.Smash" "smash-0.1.1.0-8T61bCPN60yH3RLoZzb2ua" False) (C1 (MetaCons "Nada" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "Smash" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 a) :*: S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 b))) |

# Combinators

hulkSmash :: a -> b -> Wedge a b -> Smash a b Source #

Take the smash product of a wedge and two default values to place in either the left or right side of the final product

## Eliminators

# Filtering

# Folding

foldSmashes :: Foldable f => (a -> b -> m -> m) -> m -> f (Smash a b) -> m Source #

gatherSmashes :: Smash [a] [b] -> [Smash a b] Source #

# Partitioning

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

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

# Currying & Uncurrying

# Distributivity

distributeSmash :: Smash (Wedge a b) c -> Wedge (Smash a c) (Smash b c) Source #

A smash product of wedges is a wedge of smash products.
Smash products distribute over coproducts (`Wedge`

s) in pointed Hask

undistributeSmash :: Wedge (Smash a c) (Smash b c) -> Smash (Wedge a b) c Source #

A wedge of smash products is a smash product of wedges.
Smash products distribute over coproducts (`Wedge`

s) in pointed Hask

# Associativity

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

Reassociate a `Smash`

product from left to right.

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

Reassociate a `Smash`

product from right to left.