https://hackage.haskell.org/package/exotic-list-monads-1.0.1/docs/Control-Monad-List-Exotic.html * Source * Contents * Index exotic-list-monads-1.0.1: Non-standard monads on lists and non-empty lists Copyright (c) Dylan McDermott Maciej Pirog Tarmo Uustalu 2020 License MIT Maintainer maciej.adam.pirog@gmail.com Stability experimental Portability portable Safe Haskell Trustworthy Language Haskell2010 Control.Monad.List.Exotic Contents * List monads in general * Monads with finite presentation + Pointed magmas + The Global Failure monad + The Maze Walk monad + The Discrete Hybrid monad + The List Unfold monad + The Stutter monad + The Stutter-Keeper monad + The Stutter-Stutter monad * Other monads + The Mini monad + The Odd monad (?) + The Short Stutter-Keeper monad (?) Description The usual list monad is only one of infinitely many ways to turn the List functor into a monad. This module collects a number of such exotic "list monads". Most of them have been introduced in the paper Degrading Lists by Dylan McDermott, Maciej Pirog, Tarmo Uustalu (PPDP 2020). Notes: * Types marked with "(?)" have not been formally verified to be monads (yet), though they were thoroughly tested with billions of QuickCheck tests. * Monads in this module are presented in terms of join rather than >>=. In each case return is singleton (it is not known if there exists a monad on lists with a different return). * For readability, code snippets in this documentation assume the OverloadedLists and OverloadedStrings extensions, which allow us to omit some newtype constructors. Example definitions of joins of monads always skip the newtype constructors, that is, assume >>= is always defined as follows for a particular local join: m >>= f = wrap $ join $ map (unwrap . f) $ unwrap m where join = ... * The definitions of monads are optimized for readability and not run-time performance. This is because the monads in this module don't seem to be of any practical use, they are more of a theoretical curiosity. Synopsis * class Monad m => ListMonad m where + wrap :: [a] -> m a + unwrap :: m a -> [a] * newtype DualListMonad m a = DualListMonad { + unDualListMonad :: m a } * isSingle :: [a] -> Bool * class PointedMagma a where + eps :: a + (<>) :: a -> a -> a * class ListMonad m => FreeRBPM m (c :: * -> Constraint) | m -> c where + foldRBPM :: (PointedMagma a, c a) => (x -> a) -> m x -> a * class PointedMagma a => ZeroSemigroup a * newtype GlobalFailure a = GlobalFailure { + unGlobalFailure :: [a] } * class PointedMagma a => PalindromeAlgebra a * palindromize :: [a] -> [a] * newtype MazeWalk a = MazeWalk { + unMazeWalk :: [a] } * class PointedMagma a => LeaningAlgebra a * safeLast :: [a] -> [a] * newtype DiscreteHybrid a = DiscreteHybrid { + unDiscreteHybrid :: [a] } * class PointedMagma a => SkewedAlgebra a * newtype ListUnfold a = ListUnfold { + unListUnfold :: [a] } * class (KnownNat n, PointedMagma a) => StutterAlgebra n a * replicateLast :: Int -> [a] -> [a] * newtype Stutter (n :: Nat) a = Stutter { + unStutter :: [a] } * class (KnownNat n, PointedMagma a) => StutterKeeperAlgebra n a * newtype StutterKeeper (n :: Nat) a = StutterKeeper { + unStutterKeeper :: [a] } * class (KnownNat n, KnownNat m, PointedMagma a) => StutterStutterAlgebra n m a * newtype StutterStutter (n :: Nat) (m :: Nat) a = StutterStutter { + unStutterStutter :: [a] } * newtype Mini a = Mini { + unMini :: [a] } * newtype Odd a = Odd { + unOdd :: [a] } * newtype ShortStutterKeeper (n :: Nat) (p :: Nat) a = ShortStutterKeeper { + unShortStutterKeeper :: [a] } List monads in general class Monad m => ListMonad m where Source # In this module, a "list monad" is a monad in which the underlying functor is isomorphic to List. We require: wrap . unwrap == id unwrap . wrap == id There is a default implementation provided if m is known to be a list (meaning m a is an instance of IsList for all a). Minimal complete definition Nothing Methods wrap :: [a] -> m a Source # wrap :: (IsList (m a), Item (m a) ~ a) => [a] -> m a Source # unwrap :: m a -> [a] Source # unwrap :: (IsList (m a), Item (m a) ~ a) => m a -> [a] Source # Instances ListMonad [] Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> [a] Source # unwrap :: [a] -> [a] Source # ListMonad Odd Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> Odd a Source # unwrap :: Odd a -> [a] Source # ListMonad Mini Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> Mini a Source # unwrap :: Mini a -> [a] Source # ListMonad ListUnfold Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> ListUnfold a Source # unwrap :: ListUnfold a -> [a] Source # ListMonad DiscreteHybrid Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> DiscreteHybrid a Source # unwrap :: DiscreteHybrid a -> [a] Source # ListMonad MazeWalk Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> MazeWalk a Source # unwrap :: MazeWalk a -> [a] Source # ListMonad GlobalFailure Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> GlobalFailure a Source # unwrap :: GlobalFailure a -> [a] Source # KnownNat n => ListMonad (StutterKeeper n) Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> StutterKeeper n a Source # unwrap :: StutterKeeper n a -> [a] Source # KnownNat n => ListMonad (Stutter n) Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> Stutter n a Source # unwrap :: Stutter n a -> [a] Source # (KnownNat n, KnownNat p) => ListMonad (ShortStutterKeeper n p) Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> ShortStutterKeeper n p a Source # unwrap :: ShortStutterKeeper n p a -> [a] Source # (KnownNat n, KnownNat m) => ListMonad (StutterStutter n m) Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> StutterStutter n m a Source # unwrap :: StutterStutter n m a -> [a] Source # ListMonad m => ListMonad (DualListMonad m) Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> DualListMonad m a Source # unwrap :: DualListMonad m a -> [a] Source # newtype DualListMonad m a Source # Every list monad has a dual, in which join is defined as join . reverse . fmap reverse (where join is the join of the original list monad), while return is reverse . return (where return is the return of the original list monad). Constructors DualListMonad Fields * unDualListMonad :: m a Instances ListMonad m => Monad (DualListMonad m) Source # Instance details Defined in Control.Monad.List.Exotic Methods (>>=) :: DualListMonad m a -> (a -> DualListMonad m b) -> DualListMonad m b # (>>) :: DualListMonad m a -> DualListMonad m b -> DualListMonad m b # return :: a -> DualListMonad m a # fail :: String -> DualListMonad m a # Functor m => Functor (DualListMonad m) Source # Instance details Defined in Control.Monad.List.Exotic Methods fmap :: (a -> b) -> DualListMonad m a -> DualListMonad m b # (<$) :: a -> DualListMonad m b -> DualListMonad m a # ListMonad m => Applicative (DualListMonad m) Source # Instance details Defined in Control.Monad.List.Exotic Methods pure :: a -> DualListMonad m a # (<*>) :: DualListMonad m (a -> b) -> DualListMonad m a -> DualListMonad m b # liftA2 :: (a -> b -> c) -> DualListMonad m a -> DualListMonad m b -> DualListMonad m c # (*>) :: DualListMonad m a -> DualListMonad m b -> DualListMonad m b # (<*) :: DualListMonad m a -> DualListMonad m b -> DualListMonad m a # ListMonad m => ListMonad (DualListMonad m) Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> DualListMonad m a Source # unwrap :: DualListMonad m a -> [a] Source # (ListMonad m, IsList (m a)) => IsList (DualListMonad m a) Source # Instance details Defined in Control.Monad.List.Exotic Associated Types type Item (DualListMonad m a) :: Type # Methods fromList :: [Item (DualListMonad m a)] -> DualListMonad m a # fromListN :: Int -> [Item (DualListMonad m a)] -> DualListMonad m a # toList :: DualListMonad m a -> [Item (DualListMonad m a)] # type Item (DualListMonad m a) Source # Instance details Defined in Control.Monad.List.Exotic type Item (DualListMonad m a) = Item (m a) isSingle :: [a] -> Bool Source # Checks if a given list is a singleton (= list of length one). Monads with finite presentation This section contains monads that come about from free algebras of theories with a finite number of operations, represented as type classes. Coincidentally, all theories in this module have one binary and one nullary operation, that is, each is a subclass of PointedMagma with additional laws. (So does the usual list monad, where the subclass is monoid.) It is not known if there exists a list monad that have a finite presentation but necessarily with a different set of operations (there are such monads on non-empty lists, for example, HeadTails and HeadsTail). Pointed magmas class PointedMagma a where Source # Pointed magmas are structures with one binary operation and one constant. In general, no laws are imposed. Methods eps :: a Source # (<>) :: a -> a -> a Source # Instances PointedMagma [a] Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: [a] Source # (<>) :: [a] -> [a] -> [a] Source # PointedMagma (ListUnfold a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: ListUnfold a Source # (<>) :: ListUnfold a -> ListUnfold a -> ListUnfold a Source # PointedMagma (DiscreteHybrid a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: DiscreteHybrid a Source # (<>) :: DiscreteHybrid a -> DiscreteHybrid a -> DiscreteHybrid a Source # PointedMagma (MazeWalk a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: MazeWalk a Source # (<>) :: MazeWalk a -> MazeWalk a -> MazeWalk a Source # PointedMagma (GlobalFailure a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: GlobalFailure a Source # (<>) :: GlobalFailure a -> GlobalFailure a -> GlobalFailure a Source # KnownNat n => PointedMagma (StutterKeeper n a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: StutterKeeper n a Source # (<>) :: StutterKeeper n a -> StutterKeeper n a -> StutterKeeper n a Source # KnownNat n => PointedMagma (Stutter n a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: Stutter n a Source # (<>) :: Stutter n a -> Stutter n a -> Stutter n a Source # (KnownNat n, KnownNat m) => PointedMagma (StutterStutter n m a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: StutterStutter n m a Source # (<>) :: StutterStutter n m a -> StutterStutter n m a -> StutterStutter n m a Source # class ListMonad m => FreeRBPM m (c :: * -> Constraint) | m -> c where Source # A class for free right-braketed (subclasses of) pointed magmas. Most of the monads defined in this module arise from subclasses of PointedMagma, in which we do not assume any additional methods, but require the instances to satisfy additional equations. This means that the monad is not only an instance of such a class that defines a type of algebra, but it is free such algebra. In particular, we consider theories c in which the equations have the following shapes: x <> eps == ... eps <> x == ... (x <> y) <> z == ... Moreover, when read left-to-right, they form a terminating and confluent rewriting system with normal forms of the following shape: eps x <> (y <> ( ... (z <> t) ... )) This class offers a witness that a particular list monad m is a free algebra of the theory c. This gives us the function foldRBPM _ (unwrap -> []) = eps foldRBPM f (unwrap -> xs) = foldr1 (<>) (map f xs) which is the unique lifting of an interpretation of generators to a homomorphism (between algebras of this sort) from the list monad to any algebra (an instance) of c. Note that the default definition of foldRBPM is always the right one for right-bracketed subclasses of PointedMagma, so it is enough to declare the relationship, for example: instance FreeRBPM [] Monoid Minimal complete definition Nothing Methods foldRBPM :: (PointedMagma a, c a) => (x -> a) -> m x -> a Source # Instances FreeRBPM [] Monoid Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, Monoid a) => (x -> a) -> [x] -> a Source # FreeRBPM ListUnfold SkewedAlgebra Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, SkewedAlgebra a) => (x -> a) -> ListUnfold x -> a Source # FreeRBPM DiscreteHybrid LeaningAlgebra Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, LeaningAlgebra a) => (x -> a) -> DiscreteHybrid x -> a Source # FreeRBPM MazeWalk PalindromeAlgebra Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, PalindromeAlgebra a) => (x -> a) -> MazeWalk x -> a Source # FreeRBPM GlobalFailure ZeroSemigroup Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, ZeroSemigroup a) => (x -> a) -> GlobalFailure x -> a Source # KnownNat n => FreeRBPM (StutterKeeper n) (StutterKeeperAlgebra n) Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, StutterKeeperAlgebra n a) => (x -> a) -> StutterKeeper n x -> a Source # KnownNat n => FreeRBPM (Stutter n) (StutterAlgebra n) Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, StutterAlgebra n a) => (x -> a) -> Stutter n x -> a Source # (KnownNat n, KnownNat m) => FreeRBPM (StutterStutter n m) ( StutterStutterAlgebra n m) Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, StutterStutterAlgebra n m a) => (x -> a) -> StutterStutter n m x -> a Source # The Global Failure monad class PointedMagma a => ZeroSemigroup a Source # A zero semigroup has an associative binary operation and a constant that is absorbing on both sides. That is, the following equations hold: x <> eps == eps eps <> x == eps (x <> y) <> z == x <> (y <> z) Instances FreeRBPM GlobalFailure ZeroSemigroup Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, ZeroSemigroup a) => (x -> a) -> GlobalFailure x -> a Source # ZeroSemigroup (GlobalFailure a) Source # Instance details Defined in Control.Monad.List.Exotic newtype GlobalFailure a Source # The Global Failure monad arises from free zero semigroups. It implements a kind of nondeterminism similar to the usual List monad, but failing (= producing an empty list) in one branch makes the entire computation fail. Its join is defined as: join xss | any null xss = [] | otherwise = concat xss For example: >>> [1, 2, 3] >>= (\n -> [1..n]) :: GlobalFailure Int GlobalFailure [1,1,2,1,2,3] >>> [1, 0, 3] >>= (\n -> [1..n]) :: GlobalFailure Int GlobalFailure [] Constructors GlobalFailure Fields * unGlobalFailure :: [a] Instances Monad GlobalFailure Source # Instance details Defined in Control.Monad.List.Exotic Methods (>>=) :: GlobalFailure a -> (a -> GlobalFailure b) -> GlobalFailure b # (>>) :: GlobalFailure a -> GlobalFailure b -> GlobalFailure b # return :: a -> GlobalFailure a # fail :: String -> GlobalFailure a # Functor GlobalFailure Source # Instance details Defined in Control.Monad.List.Exotic Methods fmap :: (a -> b) -> GlobalFailure a -> GlobalFailure b # (<$) :: a -> GlobalFailure b -> GlobalFailure a # Applicative GlobalFailure Source # Instance details Defined in Control.Monad.List.Exotic Methods pure :: a -> GlobalFailure a # (<*>) :: GlobalFailure (a -> b) -> GlobalFailure a -> GlobalFailure b # liftA2 :: (a -> b -> c) -> GlobalFailure a -> GlobalFailure b -> GlobalFailure c # (*>) :: GlobalFailure a -> GlobalFailure b -> GlobalFailure b # (<*) :: GlobalFailure a -> GlobalFailure b -> GlobalFailure a # ListMonad GlobalFailure Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> GlobalFailure a Source # unwrap :: GlobalFailure a -> [a] Source # FreeRBPM GlobalFailure ZeroSemigroup Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, ZeroSemigroup a) => (x -> a) -> GlobalFailure x -> a Source # IsList (GlobalFailure a) Source # Instance details Defined in Control.Monad.List.Exotic Associated Types type Item (GlobalFailure a) :: Type # Methods fromList :: [Item (GlobalFailure a)] -> GlobalFailure a # fromListN :: Int -> [Item (GlobalFailure a)] -> GlobalFailure a # toList :: GlobalFailure a -> [Item (GlobalFailure a)] # Eq a => Eq (GlobalFailure a) Source # Instance details Defined in Control.Monad.List.Exotic Methods (==) :: GlobalFailure a -> GlobalFailure a -> Bool # (/=) :: GlobalFailure a -> GlobalFailure a -> Bool # Show a => Show (GlobalFailure a) Source # Instance details Defined in Control.Monad.List.Exotic Methods showsPrec :: Int -> GlobalFailure a -> ShowS # show :: GlobalFailure a -> String # showList :: [GlobalFailure a] -> ShowS # IsString (GlobalFailure Char) Source # Instance details Defined in Control.Monad.List.Exotic Methods fromString :: String -> GlobalFailure Char # ZeroSemigroup (GlobalFailure a) Source # Instance details Defined in Control.Monad.List.Exotic PointedMagma (GlobalFailure a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: GlobalFailure a Source # (<>) :: GlobalFailure a -> GlobalFailure a -> GlobalFailure a Source # type Item (GlobalFailure a) Source # Instance details Defined in Control.Monad.List.Exotic type Item (GlobalFailure a) = a The Maze Walk monad class PointedMagma a => PalindromeAlgebra a Source # A palindrome algebra is a pointed magma that satisfies the following equations: x <> eps == eps eps <> x == eps (x <> y) <> z == x <> (y <> (x <> z)) Instances FreeRBPM MazeWalk PalindromeAlgebra Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, PalindromeAlgebra a) => (x -> a) -> MazeWalk x -> a Source # PalindromeAlgebra (MazeWalk a) Source # Instance details Defined in Control.Monad.List.Exotic palindromize :: [a] -> [a] Source # Turns a list into a palindrome by appending it and its reversed init. For example: palindromize [] == [] palindromize "Ringo" == "RingogniR" newtype MazeWalk a Source # The Maze Walk monad arises from free palindrome algebras. Its join is defined as: join xss | null xss = [] | any null xss = [] | otherwise = concatMap palindromize (init xss) ++ last xss Intuitively, it is a list of values one encounters when walking a path in a maze. The bind operation attaches to each value a new "corridor" to visit. In our walk we explore every such corridor. For example, consider the following expression: >>> join ["John", "Paul", "George", "Ringo"] :: MazeWalk Char MazeWalk "JohnhoJPauluaPGeorgegroeGRingo" It represents a walk through the following maze (the entrance is marked with ">"): +----+------+ |L U | N G O| +-+A + I+---+ > J P G R| +-+O + E ++ |N H | O +--+ +----+ R G E| +------+ First, we take the J-O-H-N path. When we reach its end, we turn around and go back to J, so our walk to this point is J-O-H-N-H-O-J (hence the connection with palindromes). Then, we explore the P-A-U-L corridor, adding P-A-U-L-U-A-P to our walk. The same applies to G-E-O-R-G-E. But when at the end of R-I-N-G-O, we have explored the entire maze, so our walk is done (this is why we do not palindromize the last element). Constructors MazeWalk Fields * unMazeWalk :: [a] Instances Monad MazeWalk Source # Instance details Defined in Control.Monad.List.Exotic Methods (>>=) :: MazeWalk a -> (a -> MazeWalk b) -> MazeWalk b # (>>) :: MazeWalk a -> MazeWalk b -> MazeWalk b # return :: a -> MazeWalk a # fail :: String -> MazeWalk a # Functor MazeWalk Source # Instance details Defined in Control.Monad.List.Exotic Methods fmap :: (a -> b) -> MazeWalk a -> MazeWalk b # (<$) :: a -> MazeWalk b -> MazeWalk a # Applicative MazeWalk Source # Instance details Defined in Control.Monad.List.Exotic Methods pure :: a -> MazeWalk a # (<*>) :: MazeWalk (a -> b) -> MazeWalk a -> MazeWalk b # liftA2 :: (a -> b -> c) -> MazeWalk a -> MazeWalk b -> MazeWalk c # (*>) :: MazeWalk a -> MazeWalk b -> MazeWalk b # (<*) :: MazeWalk a -> MazeWalk b -> MazeWalk a # ListMonad MazeWalk Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> MazeWalk a Source # unwrap :: MazeWalk a -> [a] Source # FreeRBPM MazeWalk PalindromeAlgebra Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, PalindromeAlgebra a) => (x -> a) -> MazeWalk x -> a Source # IsList (MazeWalk a) Source # Instance details Defined in Control.Monad.List.Exotic Associated Types type Item (MazeWalk a) :: Type # Methods fromList :: [Item (MazeWalk a)] -> MazeWalk a # fromListN :: Int -> [Item (MazeWalk a)] -> MazeWalk a # toList :: MazeWalk a -> [Item (MazeWalk a)] # Eq a => Eq (MazeWalk a) Source # Instance details Defined in Control.Monad.List.Exotic Methods (==) :: MazeWalk a -> MazeWalk a -> Bool # (/=) :: MazeWalk a -> MazeWalk a -> Bool # Show a => Show (MazeWalk a) Source # Instance details Defined in Control.Monad.List.Exotic Methods showsPrec :: Int -> MazeWalk a -> ShowS # show :: MazeWalk a -> String # showList :: [MazeWalk a] -> ShowS # IsString (MazeWalk Char) Source # Instance details Defined in Control.Monad.List.Exotic Methods fromString :: String -> MazeWalk Char # PalindromeAlgebra (MazeWalk a) Source # Instance details Defined in Control.Monad.List.Exotic PointedMagma (MazeWalk a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: MazeWalk a Source # (<>) :: MazeWalk a -> MazeWalk a -> MazeWalk a Source # type Item (MazeWalk a) Source # Instance details Defined in Control.Monad.List.Exotic type Item (MazeWalk a) = a The Discrete Hybrid monad class PointedMagma a => LeaningAlgebra a Source # Instances should satisfy the following: x <> eps == eps eps <> x == x (x <> y) <> z == y <> z Instances FreeRBPM DiscreteHybrid LeaningAlgebra Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, LeaningAlgebra a) => (x -> a) -> DiscreteHybrid x -> a Source # LeaningAlgebra (DiscreteHybrid a) Source # Instance details Defined in Control.Monad.List.Exotic safeLast :: [a] -> [a] Source # A singleton list with the last element of the argument, if it exists. Otherwise, empty. safeLast "Roy" == "y" safeLast [] == [] newtype DiscreteHybrid a Source # The Discrete Hybrid monad arises from free leaning algebras. Its join is defined as: join xss | null xss = [] | null (last xss) = [] | otherwise = concatMap safeLast (init xss) ++ last xss For example: >>> join ["Roy", "Kelton", "Orbison"] :: DiscreteHybrid Char DiscreteHybrid "ynOrbison" >>> join ["Roy", "", "Orbison"] :: DiscreteHybrid Char DiscreteHybrid "yOrbison" Different versions of hybrid monads originate from Renato Neves's PhD thesis. Constructors DiscreteHybrid Fields * unDiscreteHybrid :: [a] Instances Monad DiscreteHybrid Source # Instance details Defined in Control.Monad.List.Exotic Methods (>>=) :: DiscreteHybrid a -> (a -> DiscreteHybrid b) -> DiscreteHybrid b # (>>) :: DiscreteHybrid a -> DiscreteHybrid b -> DiscreteHybrid b # return :: a -> DiscreteHybrid a # fail :: String -> DiscreteHybrid a # Functor DiscreteHybrid Source # Instance details Defined in Control.Monad.List.Exotic Methods fmap :: (a -> b) -> DiscreteHybrid a -> DiscreteHybrid b # (<$) :: a -> DiscreteHybrid b -> DiscreteHybrid a # Applicative DiscreteHybrid Source # Instance details Defined in Control.Monad.List.Exotic Methods pure :: a -> DiscreteHybrid a # (<*>) :: DiscreteHybrid (a -> b) -> DiscreteHybrid a -> DiscreteHybrid b # liftA2 :: (a -> b -> c) -> DiscreteHybrid a -> DiscreteHybrid b -> DiscreteHybrid c # (*>) :: DiscreteHybrid a -> DiscreteHybrid b -> DiscreteHybrid b # (<*) :: DiscreteHybrid a -> DiscreteHybrid b -> DiscreteHybrid a # ListMonad DiscreteHybrid Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> DiscreteHybrid a Source # unwrap :: DiscreteHybrid a -> [a] Source # FreeRBPM DiscreteHybrid LeaningAlgebra Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, LeaningAlgebra a) => (x -> a) -> DiscreteHybrid x -> a Source # IsList (DiscreteHybrid a) Source # Instance details Defined in Control.Monad.List.Exotic Associated Types type Item (DiscreteHybrid a) :: Type # Methods fromList :: [Item (DiscreteHybrid a)] -> DiscreteHybrid a # fromListN :: Int -> [Item (DiscreteHybrid a)] -> DiscreteHybrid a # toList :: DiscreteHybrid a -> [Item (DiscreteHybrid a)] # Eq a => Eq (DiscreteHybrid a) Source # Instance details Defined in Control.Monad.List.Exotic Methods (==) :: DiscreteHybrid a -> DiscreteHybrid a -> Bool # (/=) :: DiscreteHybrid a -> DiscreteHybrid a -> Bool # Show a => Show (DiscreteHybrid a) Source # Instance details Defined in Control.Monad.List.Exotic Methods showsPrec :: Int -> DiscreteHybrid a -> ShowS # show :: DiscreteHybrid a -> String # showList :: [DiscreteHybrid a] -> ShowS # IsString (DiscreteHybrid Char) Source # Instance details Defined in Control.Monad.List.Exotic Methods fromString :: String -> DiscreteHybrid Char # LeaningAlgebra (DiscreteHybrid a) Source # Instance details Defined in Control.Monad.List.Exotic PointedMagma (DiscreteHybrid a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: DiscreteHybrid a Source # (<>) :: DiscreteHybrid a -> DiscreteHybrid a -> DiscreteHybrid a Source # type Item (DiscreteHybrid a) Source # Instance details Defined in Control.Monad.List.Exotic type Item (DiscreteHybrid a) = a The List Unfold monad class PointedMagma a => SkewedAlgebra a Source # A skewed algebra allows only right-nested composition of the binary operation. Every other expression is equal to eps. x <> eps == eps eps <> x == eps (x <> y) <> z == eps Instances FreeRBPM ListUnfold SkewedAlgebra Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, SkewedAlgebra a) => (x -> a) -> ListUnfold x -> a Source # SkewedAlgebra (ListUnfold a) Source # Instance details Defined in Control.Monad.List.Exotic newtype ListUnfold a Source # The List Unfold monad arises from free skewed algebras. It implements a form of nondeterminism similar to the usual list monad, but new choices may arise only in the last element (so the bind operation can only rename other elements), essentially unfolding a list. If new choices arise in the "init" of the list, the entire computation fails. Also, failure is always global. The join operation is defined as follows: join xss | null xss = [] | any null xss = [] | any (not . isSingle) (init xss) = [] | otherwise = concat xss For example: >>> [1,1,1,4] >>= \x -> [1..x] :: ListUnfold Int ListUnfold [1,1,1,1,2,3,4] >>> [1,2,1,4] >>= \x -> [1..x] :: ListUnfold Int ListUnfold [] >>> [1,0,1,4] >>= \x -> [1..x] :: ListUnfold Int ListUnfold [] Constructors ListUnfold Fields * unListUnfold :: [a] Instances Monad ListUnfold Source # Instance details Defined in Control.Monad.List.Exotic Methods (>>=) :: ListUnfold a -> (a -> ListUnfold b) -> ListUnfold b # (>>) :: ListUnfold a -> ListUnfold b -> ListUnfold b # return :: a -> ListUnfold a # fail :: String -> ListUnfold a # Functor ListUnfold Source # Instance details Defined in Control.Monad.List.Exotic Methods fmap :: (a -> b) -> ListUnfold a -> ListUnfold b # (<$) :: a -> ListUnfold b -> ListUnfold a # Applicative ListUnfold Source # Instance details Defined in Control.Monad.List.Exotic Methods pure :: a -> ListUnfold a # (<*>) :: ListUnfold (a -> b) -> ListUnfold a -> ListUnfold b # liftA2 :: (a -> b -> c) -> ListUnfold a -> ListUnfold b -> ListUnfold c # (*>) :: ListUnfold a -> ListUnfold b -> ListUnfold b # (<*) :: ListUnfold a -> ListUnfold b -> ListUnfold a # ListMonad ListUnfold Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> ListUnfold a Source # unwrap :: ListUnfold a -> [a] Source # FreeRBPM ListUnfold SkewedAlgebra Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, SkewedAlgebra a) => (x -> a) -> ListUnfold x -> a Source # IsList (ListUnfold a) Source # Instance details Defined in Control.Monad.List.Exotic Associated Types type Item (ListUnfold a) :: Type # Methods fromList :: [Item (ListUnfold a)] -> ListUnfold a # fromListN :: Int -> [Item (ListUnfold a)] -> ListUnfold a # toList :: ListUnfold a -> [Item (ListUnfold a)] # Eq a => Eq (ListUnfold a) Source # Instance details Defined in Control.Monad.List.Exotic Methods (==) :: ListUnfold a -> ListUnfold a -> Bool # (/=) :: ListUnfold a -> ListUnfold a -> Bool # Show a => Show (ListUnfold a) Source # Instance details Defined in Control.Monad.List.Exotic Methods showsPrec :: Int -> ListUnfold a -> ShowS # show :: ListUnfold a -> String # showList :: [ListUnfold a] -> ShowS # IsString (ListUnfold Char) Source # Instance details Defined in Control.Monad.List.Exotic Methods fromString :: String -> ListUnfold Char # SkewedAlgebra (ListUnfold a) Source # Instance details Defined in Control.Monad.List.Exotic PointedMagma (ListUnfold a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: ListUnfold a Source # (<>) :: ListUnfold a -> ListUnfold a -> ListUnfold a Source # type Item (ListUnfold a) Source # Instance details Defined in Control.Monad.List.Exotic type Item (ListUnfold a) = a The Stutter monad class (KnownNat n, PointedMagma a) => StutterAlgebra n a Source # A stutter algebra (for a given natural number n) is a pointed magma that satisfies the following equations: x <> eps == foldr1 (<>) (replicate (n + 2) x) eps <> x == eps (x <> y) <> z == eps Instances KnownNat n => StutterAlgebra n (Stutter n a) Source # Instance details Defined in Control.Monad.List.Exotic KnownNat n => FreeRBPM (Stutter n) (StutterAlgebra n) Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, StutterAlgebra n a) => (x -> a) -> Stutter n x -> a Source # replicateLast :: Int -> [a] -> [a] Source # Repeat the last element on the list n additional times, that is: replicateLast n [] = [] replicateLast n xs = xs ++ replicate n (last xs) newtype Stutter (n :: Nat) a Source # The Stutter monad arises from free stutter algebras. Its join is a concat of the longest prefix consisting only of singletons with a "stutter" on the last singleton (that is, the last singleton is additionally repeated n+1 times for an n fixed in the type). It doesn't stutter only when the init consists only of singletons and the last list is non-empty. The join can thus be defined as follows (omitting the conversion of the type-level Nat n to a run-time value): join xss | null xss = [] | any (not . isSingle) (init xss) || null (last xss) = replicateLast (n + 1) (concat $ takeWhile isSingle (init xss)) | otherwise = concat xss The Stutter monad is quite similar to ListUnfold. The difference is that when the latter fails (that is, its join results in an empty list), the former stutters on the last singleton. Examples: >>> join ["1", "2", "buckle", "my", "shoe"] :: Stutter 5 Char Stutter "12222222" >>> join ["1", "2", "buckle"] :: Stutter 5 Char Stutter "12buckle" >>> join ["1", "2", "", "my", "shoe"] :: Stutter 5 Char Stutter "12222222" Constructors Stutter Fields * unStutter :: [a] Instances KnownNat n => StutterAlgebra n (Stutter n a) Source # Instance details Defined in Control.Monad.List.Exotic KnownNat n => Monad (Stutter n) Source # Instance details Defined in Control.Monad.List.Exotic Methods (>>=) :: Stutter n a -> (a -> Stutter n b) -> Stutter n b # (>>) :: Stutter n a -> Stutter n b -> Stutter n b # return :: a -> Stutter n a # fail :: String -> Stutter n a # Functor (Stutter n) Source # Instance details Defined in Control.Monad.List.Exotic Methods fmap :: (a -> b) -> Stutter n a -> Stutter n b # (<$) :: a -> Stutter n b -> Stutter n a # KnownNat n => Applicative (Stutter n) Source # Instance details Defined in Control.Monad.List.Exotic Methods pure :: a -> Stutter n a # (<*>) :: Stutter n (a -> b) -> Stutter n a -> Stutter n b # liftA2 :: (a -> b -> c) -> Stutter n a -> Stutter n b -> Stutter n c # (*>) :: Stutter n a -> Stutter n b -> Stutter n b # (<*) :: Stutter n a -> Stutter n b -> Stutter n a # KnownNat n => ListMonad (Stutter n) Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> Stutter n a Source # unwrap :: Stutter n a -> [a] Source # KnownNat n => FreeRBPM (Stutter n) (StutterAlgebra n) Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, StutterAlgebra n a) => (x -> a) -> Stutter n x -> a Source # KnownNat n => IsList (Stutter n a) Source # Instance details Defined in Control.Monad.List.Exotic Associated Types type Item (Stutter n a) :: Type # Methods fromList :: [Item (Stutter n a)] -> Stutter n a # fromListN :: Int -> [Item (Stutter n a)] -> Stutter n a # toList :: Stutter n a -> [Item (Stutter n a)] # Eq a => Eq (Stutter n a) Source # Instance details Defined in Control.Monad.List.Exotic Methods (==) :: Stutter n a -> Stutter n a -> Bool # (/=) :: Stutter n a -> Stutter n a -> Bool # Show a => Show (Stutter n a) Source # Instance details Defined in Control.Monad.List.Exotic Methods showsPrec :: Int -> Stutter n a -> ShowS # show :: Stutter n a -> String # showList :: [Stutter n a] -> ShowS # KnownNat n => IsString (Stutter n Char) Source # Instance details Defined in Control.Monad.List.Exotic Methods fromString :: String -> Stutter n Char # KnownNat n => PointedMagma (Stutter n a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: Stutter n a Source # (<>) :: Stutter n a -> Stutter n a -> Stutter n a Source # type Item (Stutter n a) Source # Instance details Defined in Control.Monad.List.Exotic type Item (Stutter n a) = a The Stutter-Keeper monad class (KnownNat n, PointedMagma a) => StutterKeeperAlgebra n a Source # A stutter-keeper algebra (for a given natural number n) is a pointed magma that satisfies the following equations: x <> eps == foldr1 (<>) (replicate (n + 2) x) eps <> x == eps (x <> y) <> z == x <> y Instances KnownNat n => StutterKeeperAlgebra n (StutterKeeper n a) Source # Instance details Defined in Control.Monad.List.Exotic KnownNat n => FreeRBPM (StutterKeeper n) (StutterKeeperAlgebra n) Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, StutterKeeperAlgebra n a) => (x -> a) -> StutterKeeper n x -> a Source # newtype StutterKeeper (n :: Nat) a Source # The stutter-keeper monad arises from free stutter-keeper algebras. Its join stutters (as in the Stutter monad) if the first non-singleton list in empty. Otherwise, it keeps the singleton prefix, and keeps the first non-singleton list. The join can thus be defined as follows (omitting the conversion of the type-level Nat n to a run-time value): join xss | null xss = [] | null (head (dropWhile isSingle (init xss) ++ [last xss])) = replicateLast (n + 1) (concat $ takeWhile isSingle (init xss)) | otherwise = map head (takeWhile isSingle (init xss)) ++ head (dropWhile isSingle (init xss) ++ [last xss]) Examples: >>> join ["1", "2", "buckle", "my", "shoe"] :: StutterKeeper 5 Char StutterKeeper "12buckle" >>> join ["1", "2", "buckle"] :: StutterKeeper 5 Char StutterKeeper "12buckle" >>> join ["1", "2", "", "my", "shoe"] :: StutterKeeper 5 Char StutterKeeper "12222222" Constructors StutterKeeper Fields * unStutterKeeper :: [a] Instances KnownNat n => StutterKeeperAlgebra n (StutterKeeper n a) Source # Instance details Defined in Control.Monad.List.Exotic KnownNat n => Monad (StutterKeeper n) Source # Instance details Defined in Control.Monad.List.Exotic Methods (>>=) :: StutterKeeper n a -> (a -> StutterKeeper n b) -> StutterKeeper n b # (>>) :: StutterKeeper n a -> StutterKeeper n b -> StutterKeeper n b # return :: a -> StutterKeeper n a # fail :: String -> StutterKeeper n a # Functor (StutterKeeper n) Source # Instance details Defined in Control.Monad.List.Exotic Methods fmap :: (a -> b) -> StutterKeeper n a -> StutterKeeper n b # (<$) :: a -> StutterKeeper n b -> StutterKeeper n a # KnownNat n => Applicative (StutterKeeper n) Source # Instance details Defined in Control.Monad.List.Exotic Methods pure :: a -> StutterKeeper n a # (<*>) :: StutterKeeper n (a -> b) -> StutterKeeper n a -> StutterKeeper n b # liftA2 :: (a -> b -> c) -> StutterKeeper n a -> StutterKeeper n b -> StutterKeeper n c # (*>) :: StutterKeeper n a -> StutterKeeper n b -> StutterKeeper n b # (<*) :: StutterKeeper n a -> StutterKeeper n b -> StutterKeeper n a # KnownNat n => ListMonad (StutterKeeper n) Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> StutterKeeper n a Source # unwrap :: StutterKeeper n a -> [a] Source # KnownNat n => FreeRBPM (StutterKeeper n) (StutterKeeperAlgebra n) Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, StutterKeeperAlgebra n a) => (x -> a) -> StutterKeeper n x -> a Source # KnownNat n => IsList (StutterKeeper n a) Source # Instance details Defined in Control.Monad.List.Exotic Associated Types type Item (StutterKeeper n a) :: Type # Methods fromList :: [Item (StutterKeeper n a)] -> StutterKeeper n a # fromListN :: Int -> [Item (StutterKeeper n a)] -> StutterKeeper n a # toList :: StutterKeeper n a -> [Item (StutterKeeper n a)] # Eq a => Eq (StutterKeeper n a) Source # Instance details Defined in Control.Monad.List.Exotic Methods (==) :: StutterKeeper n a -> StutterKeeper n a -> Bool # (/=) :: StutterKeeper n a -> StutterKeeper n a -> Bool # Show a => Show (StutterKeeper n a) Source # Instance details Defined in Control.Monad.List.Exotic Methods showsPrec :: Int -> StutterKeeper n a -> ShowS # show :: StutterKeeper n a -> String # showList :: [StutterKeeper n a] -> ShowS # KnownNat n => IsString (StutterKeeper n Char) Source # Instance details Defined in Control.Monad.List.Exotic Methods fromString :: String -> StutterKeeper n Char # KnownNat n => PointedMagma (StutterKeeper n a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: StutterKeeper n a Source # (<>) :: StutterKeeper n a -> StutterKeeper n a -> StutterKeeper n a Source # type Item (StutterKeeper n a) Source # Instance details Defined in Control.Monad.List.Exotic type Item (StutterKeeper n a) = a The Stutter-Stutter monad class (KnownNat n, KnownNat m, PointedMagma a) => StutterStutterAlgebra n m a Source # A stutter-stutter algebra (for given natural numbers n and m) is a pointed magma that satisfies the following equations: x <> eps == foldr1 (<>) (replicate (n + 2) x) eps <> x == eps (x <> y) <> z == foldr1 (<>) (replicate (m + 2) x) Instances (KnownNat n, KnownNat m) => StutterStutterAlgebra n m ( StutterStutter n m a) Source # Instance details Defined in Control.Monad.List.Exotic (KnownNat n, KnownNat m) => FreeRBPM (StutterStutter n m) ( StutterStutterAlgebra n m) Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, StutterStutterAlgebra n m a) => (x -> a) -> StutterStutter n m x -> a Source # newtype StutterStutter (n :: Nat) (m :: Nat) a Source # The stutter-stutter monad arises from free stutter-stutter algebras. It is similar to StutterKeeper, but instead of keeping the first non-singleton list, it stutters on its first element (unless the first non-singleton list is also the last list, in which case it is kept in the result). The join can thus be defined as follows (omitting the conversion of the type-level nats to run-time values): join xss | null xss = [] | null (head (dropWhile isSingle (init xss) ++ [last xss])) = replicateLast (n + 1) (concat $ takeWhile isSingle (init xss)) | any (not . isSingle) (init xss) || null (last xss) = concat (takeWhile isSingle (init xss)) ++ replicate (m + 2) (head (head (dropWhile isSingle (init xss)))) | otherwise = concat xss Examples: >>> join ["1", "2", "buckle", "my", "shoe"] :: StutterStutter 5 10 Char StutterStutter "12bbbbbbbbbbbb" >>> join ["1", "2", "buckle"] :: StutterStutter 5 10 Char StutterStutter "12buckle" >>> join ["1", "2", "", "my", "shoe"] :: StutterStutter 5 10 Char StutterStutter "12222222" Constructors StutterStutter Fields * unStutterStutter :: [a] Instances (KnownNat n, KnownNat m) => StutterStutterAlgebra n m ( StutterStutter n m a) Source # Instance details Defined in Control.Monad.List.Exotic (KnownNat n, KnownNat m) => Monad (StutterStutter n m) Source # Instance details Defined in Control.Monad.List.Exotic Methods (>>=) :: StutterStutter n m a -> (a -> StutterStutter n m b) -> StutterStutter n m b # (>>) :: StutterStutter n m a -> StutterStutter n m b -> StutterStutter n m b # return :: a -> StutterStutter n m a # fail :: String -> StutterStutter n m a # Functor (StutterStutter n m) Source # Instance details Defined in Control.Monad.List.Exotic Methods fmap :: (a -> b) -> StutterStutter n m a -> StutterStutter n m b # (<$) :: a -> StutterStutter n m b -> StutterStutter n m a # (KnownNat n, KnownNat m) => Applicative (StutterStutter n m) Source # Instance details Defined in Control.Monad.List.Exotic Methods pure :: a -> StutterStutter n m a # (<*>) :: StutterStutter n m (a -> b) -> StutterStutter n m a -> StutterStutter n m b # liftA2 :: (a -> b -> c) -> StutterStutter n m a -> StutterStutter n m b -> StutterStutter n m c # (*>) :: StutterStutter n m a -> StutterStutter n m b -> StutterStutter n m b # (<*) :: StutterStutter n m a -> StutterStutter n m b -> StutterStutter n m a # (KnownNat n, KnownNat m) => ListMonad (StutterStutter n m) Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> StutterStutter n m a Source # unwrap :: StutterStutter n m a -> [a] Source # (KnownNat n, KnownNat m) => FreeRBPM (StutterStutter n m) ( StutterStutterAlgebra n m) Source # Instance details Defined in Control.Monad.List.Exotic Methods foldRBPM :: (PointedMagma a, StutterStutterAlgebra n m a) => (x -> a) -> StutterStutter n m x -> a Source # (KnownNat n, KnownNat m) => IsList (StutterStutter n m a) Source # Instance details Defined in Control.Monad.List.Exotic Associated Types type Item (StutterStutter n m a) :: Type # Methods fromList :: [Item (StutterStutter n m a)] -> StutterStutter n m a # fromListN :: Int -> [Item (StutterStutter n m a)] -> StutterStutter n m a # toList :: StutterStutter n m a -> [Item (StutterStutter n m a)] # Eq a => Eq (StutterStutter n m a) Source # Instance details Defined in Control.Monad.List.Exotic Methods (==) :: StutterStutter n m a -> StutterStutter n m a -> Bool # (/=) :: StutterStutter n m a -> StutterStutter n m a -> Bool # Show a => Show (StutterStutter n m a) Source # Instance details Defined in Control.Monad.List.Exotic Methods showsPrec :: Int -> StutterStutter n m a -> ShowS # show :: StutterStutter n m a -> String # showList :: [StutterStutter n m a] -> ShowS # (KnownNat n, KnownNat m) => IsString (StutterStutter n m Char) Source # Instance details Defined in Control.Monad.List.Exotic Methods fromString :: String -> StutterStutter n m Char # (KnownNat n, KnownNat m) => PointedMagma (StutterStutter n m a) Source # Instance details Defined in Control.Monad.List.Exotic Methods eps :: StutterStutter n m a Source # (<>) :: StutterStutter n m a -> StutterStutter n m a -> StutterStutter n m a Source # type Item (StutterStutter n m a) Source # Instance details Defined in Control.Monad.List.Exotic type Item (StutterStutter n m a) = a Other monads While all list monads have presentations in terms of operations and equations, some require infinitely many operations. This section contains monads that are either known to require infinitely many operations, or those for which no finite presentation is known, but we don't know for sure that such a presentation doesn't exist. The Mini monad newtype Mini a Source # The Mini monad is the minimal list monad, meaning that its join fails (= results in an empty list) for all values except the ones that appear in the unit laws (i.e., a singleton or a list of singletons): join xss | isSingle xss = concat xss | all isSingle xss = concat xss | otherwise = [] For example: >>> join ["HelloThere"] :: Mini Char Mini "HelloThere" >>> join ["Hello", "There"] :: Mini Char Mini "" It does not arise from a subclass of PointedMagma (or any algebraic theory with a finite number of operations for that matter). Constructors Mini Fields * unMini :: [a] Instances Monad Mini Source # Instance details Defined in Control.Monad.List.Exotic Methods (>>=) :: Mini a -> (a -> Mini b) -> Mini b # (>>) :: Mini a -> Mini b -> Mini b # return :: a -> Mini a # fail :: String -> Mini a # Functor Mini Source # Instance details Defined in Control.Monad.List.Exotic Methods fmap :: (a -> b) -> Mini a -> Mini b # (<$) :: a -> Mini b -> Mini a # Applicative Mini Source # Instance details Defined in Control.Monad.List.Exotic Methods pure :: a -> Mini a # (<*>) :: Mini (a -> b) -> Mini a -> Mini b # liftA2 :: (a -> b -> c) -> Mini a -> Mini b -> Mini c # (*>) :: Mini a -> Mini b -> Mini b # (<*) :: Mini a -> Mini b -> Mini a # ListMonad Mini Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> Mini a Source # unwrap :: Mini a -> [a] Source # IsList (Mini a) Source # Instance details Defined in Control.Monad.List.Exotic Associated Types type Item (Mini a) :: Type # Methods fromList :: [Item (Mini a)] -> Mini a # fromListN :: Int -> [Item (Mini a)] -> Mini a # toList :: Mini a -> [Item (Mini a)] # Eq a => Eq (Mini a) Source # Instance details Defined in Control.Monad.List.Exotic Methods (==) :: Mini a -> Mini a -> Bool # (/=) :: Mini a -> Mini a -> Bool # Show a => Show (Mini a) Source # Instance details Defined in Control.Monad.List.Exotic Methods showsPrec :: Int -> Mini a -> ShowS # show :: Mini a -> String # showList :: [Mini a] -> ShowS # IsString (Mini Char) Source # Instance details Defined in Control.Monad.List.Exotic Methods fromString :: String -> Mini Char # type Item (Mini a) Source # Instance details Defined in Control.Monad.List.Exotic type Item (Mini a) = a The Odd monad (?) newtype Odd a Source # The join of the Odd monad is a concat of the inner lists provided there is an odd number of them, and that all of them are of odd length themselves. Otherwise (modulo cases needed for the unit laws), it returns an empty list. join xss | isSingle xss = concat xss | all isSingle xss = concat xss | odd (length xss) && all (odd . length) xss = concat xss | otherwise = [] For example: >>> join ["Elvis", "Presley"] :: Odd Char Odd "" >>> join ["Elvis", "Aaron", "Presley"] :: Odd Char Odd "ElvisAaronPresley" >>> join ["Roy", "Kelton", "Orbison"] :: Odd Char Odd "" At the moment, it is unclear whether it comes from a finite algebraic theory (or that it is indeed a monad). Constructors Odd Fields * unOdd :: [a] Instances Monad Odd Source # Instance details Defined in Control.Monad.List.Exotic Methods (>>=) :: Odd a -> (a -> Odd b) -> Odd b # (>>) :: Odd a -> Odd b -> Odd b # return :: a -> Odd a # fail :: String -> Odd a # Functor Odd Source # Instance details Defined in Control.Monad.List.Exotic Methods fmap :: (a -> b) -> Odd a -> Odd b # (<$) :: a -> Odd b -> Odd a # Applicative Odd Source # Instance details Defined in Control.Monad.List.Exotic Methods pure :: a -> Odd a # (<*>) :: Odd (a -> b) -> Odd a -> Odd b # liftA2 :: (a -> b -> c) -> Odd a -> Odd b -> Odd c # (*>) :: Odd a -> Odd b -> Odd b # (<*) :: Odd a -> Odd b -> Odd a # ListMonad Odd Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> Odd a Source # unwrap :: Odd a -> [a] Source # IsList (Odd a) Source # Instance details Defined in Control.Monad.List.Exotic Associated Types type Item (Odd a) :: Type # Methods fromList :: [Item (Odd a)] -> Odd a # fromListN :: Int -> [Item (Odd a)] -> Odd a # toList :: Odd a -> [Item (Odd a)] # Eq a => Eq (Odd a) Source # Instance details Defined in Control.Monad.List.Exotic Methods (==) :: Odd a -> Odd a -> Bool # (/=) :: Odd a -> Odd a -> Bool # Show a => Show (Odd a) Source # Instance details Defined in Control.Monad.List.Exotic Methods showsPrec :: Int -> Odd a -> ShowS # show :: Odd a -> String # showList :: [Odd a] -> ShowS # IsString (Odd Char) Source # Instance details Defined in Control.Monad.List.Exotic Methods fromString :: String -> Odd Char # type Item (Odd a) Source # Instance details Defined in Control.Monad.List.Exotic type Item (Odd a) = a The Short Stutter-Keeper monad (?) newtype ShortStutterKeeper (n :: Nat) (p :: Nat) a Source # This monad works just like the StutterKeeper monad but it takes a prefix of the result of join of length p+2 (unless the unit laws say otherwise). Thus, its join is defined as follows (omitting the conversion of the type-level Nat p to a run-time value): join xss | isSingle xss = concat xss | all isSingle xss = concat xss | otherwise = take (p + 2) $ toList ((Control.Monad.join $ StutterKeeper $ fmap StutterKeeper xss) :: StutterKeeper n _) For example: >>> join ["1", "2", "buckle", "my", "shoe"] :: ShortStutterKeeper 5 2 Char ShortStutterKeeper "12bu" >>> join ["1", "2", "buckle"] :: ShortStutterKeeper 5 2 Char ShortStutterKeeper "12bu" >>> join ["1", "2", "", "my", "shoe"] :: ShortStutterKeeper 5 2 Char ShortStutterKeeper "1222" Compare the ShortFront monad on non-empty lists. Constructors ShortStutterKeeper Fields * unShortStutterKeeper :: [a] Instances (KnownNat n, KnownNat p) => Monad (ShortStutterKeeper n p) Source # Instance details Defined in Control.Monad.List.Exotic Methods (>>=) :: ShortStutterKeeper n p a -> (a -> ShortStutterKeeper n p b) -> ShortStutterKeeper n p b # (>>) :: ShortStutterKeeper n p a -> ShortStutterKeeper n p b -> ShortStutterKeeper n p b # return :: a -> ShortStutterKeeper n p a # fail :: String -> ShortStutterKeeper n p a # Functor (ShortStutterKeeper n p) Source # Instance details Defined in Control.Monad.List.Exotic Methods fmap :: (a -> b) -> ShortStutterKeeper n p a -> ShortStutterKeeper n p b # (<$) :: a -> ShortStutterKeeper n p b -> ShortStutterKeeper n p a # (KnownNat n, KnownNat p) => Applicative (ShortStutterKeeper n p) Source # Instance details Defined in Control.Monad.List.Exotic Methods pure :: a -> ShortStutterKeeper n p a # (<*>) :: ShortStutterKeeper n p (a -> b) -> ShortStutterKeeper n p a -> ShortStutterKeeper n p b # liftA2 :: (a -> b -> c) -> ShortStutterKeeper n p a -> ShortStutterKeeper n p b -> ShortStutterKeeper n p c # (*>) :: ShortStutterKeeper n p a -> ShortStutterKeeper n p b -> ShortStutterKeeper n p b # (<*) :: ShortStutterKeeper n p a -> ShortStutterKeeper n p b -> ShortStutterKeeper n p a # (KnownNat n, KnownNat p) => ListMonad (ShortStutterKeeper n p) Source # Instance details Defined in Control.Monad.List.Exotic Methods wrap :: [a] -> ShortStutterKeeper n p a Source # unwrap :: ShortStutterKeeper n p a -> [a] Source # (KnownNat n, KnownNat p) => IsList (ShortStutterKeeper n p a) Source # Instance details Defined in Control.Monad.List.Exotic Associated Types type Item (ShortStutterKeeper n p a) :: Type # Methods fromList :: [Item (ShortStutterKeeper n p a)] -> ShortStutterKeeper n p a # fromListN :: Int -> [Item (ShortStutterKeeper n p a)] -> ShortStutterKeeper n p a # toList :: ShortStutterKeeper n p a -> [Item (ShortStutterKeeper n p a)] # Eq a => Eq (ShortStutterKeeper n p a) Source # Instance details Defined in Control.Monad.List.Exotic Methods (==) :: ShortStutterKeeper n p a -> ShortStutterKeeper n p a -> Bool # (/=) :: ShortStutterKeeper n p a -> ShortStutterKeeper n p a -> Bool # Show a => Show (ShortStutterKeeper n p a) Source # Instance details Defined in Control.Monad.List.Exotic Methods showsPrec :: Int -> ShortStutterKeeper n p a -> ShowS # show :: ShortStutterKeeper n p a -> String # showList :: [ShortStutterKeeper n p a] -> ShowS # (KnownNat n, KnownNat p) => IsString (ShortStutterKeeper n p Char) Source # Instance details Defined in Control.Monad.List.Exotic Methods fromString :: String -> ShortStutterKeeper n p Char # type Item (ShortStutterKeeper n p a) Source # Instance details Defined in Control.Monad.List.Exotic type Item (ShortStutterKeeper n p a) = a Produced by Haddock version 2.22.0