smash-0.1.2: Combinators for Maybe types
Copyright(c) 2020-2021 Emily Pillmore
LicenseBSD-3-Clause
MaintainerEmily Pillmore <emilypi@cohomolo.gy>
StabilityExperimental
PortabilityCPP, RankNTypes, TypeApplications
Safe HaskellSafe
LanguageHaskell2010

Data.Smash

Description

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

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.

data Smash a b Source #

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

Constructors

Nada 
Smash a b 

Instances

Instances details
Bitraversable Smash Source # 
Instance details

Defined in Data.Smash

Methods

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

Bifoldable Smash Source # 
Instance details

Defined in Data.Smash

Methods

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

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

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

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

Bifunctor Smash Source # 
Instance details

Defined in Data.Smash

Methods

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

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

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

Eq2 Smash Source # 
Instance details

Defined in Data.Smash

Methods

liftEq2 :: (a -> b -> Bool) -> (c -> d -> Bool) -> Smash a c -> Smash b d -> Bool #

Ord2 Smash Source # 
Instance details

Defined in Data.Smash

Methods

liftCompare2 :: (a -> b -> Ordering) -> (c -> d -> Ordering) -> Smash a c -> Smash b d -> Ordering #

Read2 Smash Source # 
Instance details

Defined in Data.Smash

Methods

liftReadsPrec2 :: (Int -> ReadS a) -> ReadS [a] -> (Int -> ReadS b) -> ReadS [b] -> Int -> ReadS (Smash a b) #

liftReadList2 :: (Int -> ReadS a) -> ReadS [a] -> (Int -> ReadS b) -> ReadS [b] -> ReadS [Smash a b] #

liftReadPrec2 :: ReadPrec a -> ReadPrec [a] -> ReadPrec b -> ReadPrec [b] -> ReadPrec (Smash a b) #

liftReadListPrec2 :: ReadPrec a -> ReadPrec [a] -> ReadPrec b -> ReadPrec [b] -> ReadPrec [Smash a b] #

Show2 Smash Source # 
Instance details

Defined in Data.Smash

Methods

liftShowsPrec2 :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS) -> Int -> Smash a b -> ShowS #

liftShowList2 :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS) -> [Smash a b] -> ShowS #

NFData2 Smash Source # 
Instance details

Defined in Data.Smash

Methods

liftRnf2 :: (a -> ()) -> (b -> ()) -> Smash a b -> () #

Biapplicative Smash Source # 
Instance details

Defined in Data.Smash

Methods

bipure :: a -> b -> Smash a b

(<<*>>) :: Smash (a -> b) (c -> d) -> Smash a c -> Smash b d

biliftA2 :: (a -> b -> c) -> (d -> e -> f) -> Smash a d -> Smash b e -> Smash c f

(*>>) :: Smash a b -> Smash c d -> Smash c d

(<<*) :: Smash a b -> Smash c d -> Smash a b

Hashable2 Smash Source # 
Instance details

Defined in Data.Smash

Methods

liftHashWithSalt2 :: (Int -> a -> Int) -> (Int -> b -> Int) -> Int -> Smash a b -> Int

Monoid a => Monad (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

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

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

return :: a0 -> Smash a a0 #

Functor (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

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

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

Monoid a => Applicative (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

pure :: a0 -> Smash a a0 #

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

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

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

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

Eq a => Eq1 (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

liftEq :: (a0 -> b -> Bool) -> Smash a a0 -> Smash a b -> Bool #

Ord a => Ord1 (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

liftCompare :: (a0 -> b -> Ordering) -> Smash a a0 -> Smash a b -> Ordering #

Read a => Read1 (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

liftReadsPrec :: (Int -> ReadS a0) -> ReadS [a0] -> Int -> ReadS (Smash a a0) #

liftReadList :: (Int -> ReadS a0) -> ReadS [a0] -> ReadS [Smash a a0] #

liftReadPrec :: ReadPrec a0 -> ReadPrec [a0] -> ReadPrec (Smash a a0) #

liftReadListPrec :: ReadPrec a0 -> ReadPrec [a0] -> ReadPrec [Smash a a0] #

Show a => Show1 (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

liftShowsPrec :: (Int -> a0 -> ShowS) -> ([a0] -> ShowS) -> Int -> Smash a a0 -> ShowS #

liftShowList :: (Int -> a0 -> ShowS) -> ([a0] -> ShowS) -> [Smash a a0] -> ShowS #

Monoid a => MonadZip (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

mzip :: Smash a a0 -> Smash a b -> Smash a (a0, b) #

mzipWith :: (a0 -> b -> c) -> Smash a a0 -> Smash a b -> Smash a c #

munzip :: Smash a (a0, b) -> (Smash a a0, Smash a b) #

Monoid a => Alternative (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

empty :: Smash a a0 #

(<|>) :: Smash a a0 -> Smash a a0 -> Smash a a0 #

some :: Smash a a0 -> Smash a [a0] #

many :: Smash a a0 -> Smash a [a0] #

Monoid a => MonadPlus (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

mzero :: Smash a a0 #

mplus :: Smash a a0 -> Smash a a0 -> Smash a a0 #

NFData a => NFData1 (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

liftRnf :: (a0 -> ()) -> Smash a a0 -> () #

Hashable a => Hashable1 (Smash a) Source # 
Instance details

Defined in Data.Smash

Methods

liftHashWithSalt :: (Int -> a0 -> Int) -> Int -> Smash a a0 -> Int

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

Defined in Data.Smash

Associated Types

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

Methods

from1 :: forall (a0 :: k). Smash a a0 -> Rep1 (Smash a) a0 #

to1 :: forall (a0 :: k). Rep1 (Smash a) a0 -> Smash a a0 #

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

Defined in Data.Smash

Methods

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

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

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

Defined in Data.Smash

Methods

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 :: forall r r'. (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 # 
Instance details

Defined in Data.Smash

Methods

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

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

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

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

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

max :: Smash a b -> Smash a b -> Smash a b #

min :: Smash a b -> Smash a b -> Smash a b #

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

Defined in Data.Smash

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

Defined in Data.Smash

Methods

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

show :: Smash a b -> String #

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

Generic (Smash a b) Source # 
Instance details

Defined in Data.Smash

Associated Types

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

Methods

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

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

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

Defined in Data.Smash

Methods

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

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

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

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

Defined in Data.Smash

Methods

mempty :: Smash a b #

mappend :: Smash a b -> Smash a b -> Smash a b #

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

(Lift a, Lift b) => Lift (Smash a b) Source # 
Instance details

Defined in Data.Smash

Methods

lift :: Smash a b -> Q Exp #

(Binary a, Binary b) => Binary (Smash a b) Source # 
Instance details

Defined in Data.Smash

Methods

put :: Smash a b -> Put #

get :: Get (Smash a b) #

putList :: [Smash a b] -> Put #

(NFData a, NFData b) => NFData (Smash a b) Source # 
Instance details

Defined in Data.Smash

Methods

rnf :: Smash a b -> () #

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

Defined in Data.Smash

Methods

hashWithSalt :: Int -> Smash a b -> Int

hash :: Smash a b -> Int

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

Defined in Data.Smash

type Rep (Smash a b) Source # 
Instance details

Defined in Data.Smash

type Rep (Smash a b) = D1 ('MetaData "Smash" "Data.Smash" "smash-0.1.2-inplace" '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)))

Type synonyms

type (⨳) a b = Smash a b Source #

A type operator synonym for Smash

Combinators

toSmash :: Maybe (a, b) -> Smash a b Source #

Convert a Maybe value into a Smash value

fromSmash :: Smash a b -> Maybe (a, b) Source #

Convert a Smash value into a Maybe value

smashFst :: Smash a b -> Maybe a Source #

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

smashSnd :: Smash a b -> Maybe b Source #

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

quotSmash :: Can a b -> Smash a b Source #

Smash product of pointed type modulo its wedge

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

isSmash :: Smash a b -> Bool Source #

Detect whether a Smash value is not empty

isNada :: Smash a b -> Bool Source #

Detect whether a Smash value is empty

smashDiag :: Maybe a -> Smash a a Source #

Create a smash product of self-similar values from a pointed object.

This is the diagonal morphism in Hask*.

smashDiag' :: a -> Smash a a Source #

See: smashDiag. This is always a Smash value.

Eliminators

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

Case elimination for the Smash datatype

Filtering

smashes :: Foldable f => f (Smash a b) -> [(a, b)] Source #

Given a Foldable of Smashs, collect the values of the Smash cases, if any.

filterNadas :: Foldable f => f (Smash a b) -> [Smash a b] Source #

Filter the Nada cases of a Foldable of Smash values.

Folding and Unfolding

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

Fold over the Smash case of a Foldable of Smash products by some accumulating function.

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

Gather a Smash product of two lists and product a list of Smash values, mapping the Nada case to the empty list and zipping the two lists together with the Smash constructor otherwise.

unfoldr :: Alternative f => (b -> Smash a b) -> b -> f a Source #

Unfold from right to left into a smash product

unfoldrM :: (Monad m, Alternative f) => (b -> m (Smash a b)) -> b -> m (f a) Source #

Unfold from right to left into a monadic computation over a smash product

iterateUntil :: Alternative f => (b -> Smash a b) -> b -> f a Source #

Iterate on a seed, accumulating a result. See iterateUntilM for more details.

iterateUntilM :: Monad m => Alternative f => (b -> m (Smash a b)) -> b -> m (f a) Source #

Iterate on a seed, which may result in one of two scenarios:

  1. The function yields a Nada value, which terminates the iteration.
  2. The function yields a Smash value.

accumUntil :: Alternative f => Monoid b => (b -> Smash a b) -> f a Source #

Iterate on a seed, accumulating values and monoidally updating the seed with each update.

accumUntilM :: Monad m => Alternative f => Monoid b => (b -> m (Smash a b)) -> m (f a) Source #

Iterate on a seed, accumulating values and monoidally updating a seed within a monad.

Partitioning

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

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

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

Partition a structure by mapping its contents into Smashs, and folding over (<|>).

Currying & Uncurrying

smashCurry :: (Smash a b -> Maybe c) -> Maybe a -> Maybe b -> Maybe c Source #

Curry a map from a smash product to a pointed type. This is analogous to curry for ('->').

smashUncurry :: (Maybe a -> Maybe b -> Maybe c) -> Smash a b -> Maybe c Source #

Uncurry a map of pointed types to a map of a smash product to a pointed type. This is analogous to uncurry for ('->').

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 (Wedges) 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 (Wedges) in pointed Hask

pairSmash :: Smash (a, b) c -> (Smash a c, Smash b c) Source #

Distribute a Smash of a pair into a pair of Smashs

unpairSmash :: (Smash a c, Smash b c) -> Smash (a, b) c Source #

Distribute a Smash of a pair into a pair of Smashs

pairSmashCan :: Smash (Can a b) c -> Can (Smash a c) (Smash b c) Source #

Distribute a Smash of a Can into a Can of Smashs

unpairSmashCan :: Can (Smash a c) (Smash b c) -> Smash (Can a b) c Source #

Undistribute a Can of Smashs into a Smash of Cans.

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.

Symmetry

swapSmash :: Smash a b -> Smash b a Source #

Swap the positions of values in a Smash a b to form a Smash b a.