smash-0.1.3: Combinators for Maybe types
Copyright (c) 2020-2022 Emily Pillmore BSD-3-Clause Emily Pillmore Experimental CPP, RankNTypes, TypeApplications Safe Haskell2010

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:



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

#### Instances

Instances details

## 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 :: Alternative f => Foldable t => 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 (<|>).

Equivalence relation formed by grouping of equal Smash constructors.

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