-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Express the minimum length of a container in its type -- -- Please see README.md @package minlen @version 0.1.0.0 module Data.MinLen -- | Zero is the base value for the Peano numbers. data Zero Zero :: Zero -- | Succ represents the next number in the sequence of natural -- numbers. -- -- It takes a nat (a natural number) as an argument. -- -- Zero is a nat, allowing Succ -- Zero to represent 1. -- -- Succ is also a nat, so it can be applied to itself, -- allowing Succ (Succ Zero) to represent -- 2, Succ (Succ (Succ Zero)) to -- represent 3, and so on. data Succ nat Succ :: nat -> Succ nat -- | Type-level natural number utility typeclass class TypeNat nat -- | Turn a type-level natural number into a number -- --
-- > toValueNat Zero -- 0 -- > toValueNat (Succ (Succ (Succ Zero))) -- 3 --toValueNat :: (TypeNat nat, Num i) => nat -> i -- | Get a data representation of a natural number type -- --
-- > typeNat :: Succ (Succ Zero) -- Succ (Succ Zero) -- Errors because Succ and Zero have no Show typeclass, -- -- But this is what it would look like if it did. --typeNat :: TypeNat nat => nat -- | Adds two type-level naturals. -- -- See the mlappend type signature for an example. -- --
-- > :t typeNat :: AddNat (Succ (Succ Zero)) (Succ Zero) -- -- typeNat :: AddNat (Succ (Succ Zero)) (Succ Zero) -- :: Succ (Succ (Succ Zero)) ---- | Calculates the maximum of two type-level naturals. -- -- See the mlunion type signature for an example. -- --
-- > :t typeNat :: MaxNat (Succ (Succ Zero)) (Succ Zero) -- -- typeNat :: MaxNat (Succ (Succ Zero)) (Succ Zero) -- :: Succ (Succ Zero) ---- | A wrapper around a container which encodes its minimum length in the -- type system. This allows functions like head and maximum -- to be made safe without using Maybe. -- -- The length, nat, is encoded as a Peano number, which -- starts with the Zero constructor and is made one larger with -- each application of Succ (Zero for 0, Succ -- Zero for 1, Succ (Succ Zero) -- for 2, etc.). Functions which require at least one element, then, are -- typed with Succ nat, where nat is either Zero -- or any number of applications of Succ: -- --
-- head :: MonoTraversable mono => MinLen (Succ nat) mono -> Element mono ---- -- The length is also a phantom type, i.e. it is only used on the -- left hand side of the type and doesn't exist at runtime. Notice how -- Succ Zero isn't included in the printed output: -- --
-- > toMinLen [1,2,3] :: Maybe (MinLen (Succ Zero) [Int])
-- Just (MinLen {unMinLen = [1,2,3]})
--
--
-- You can still use GHCI's :i command to see the phantom type
-- information:
--
-- -- > let xs = mlcons 1 $ toMinLenZero [] -- > :i xs -- xs :: Num t => MinLen (Succ Zero) [t] --data MinLen nat mono -- | Get the monomorphic container out of a MinLen wrapper. unMinLen :: MinLen nat mono -> mono -- | Types a container as having a minimum length of zero. This is useful -- when combined with other MinLen functions that increase the -- size of the container. -- --
-- > 1 `mlcons` toMinLenZero []
-- MinLen {unMinLen = [1]}
--
toMinLenZero :: (MonoFoldable mono) => mono -> MinLen Zero mono
-- | Attempts to add a MinLen constraint to a monomorphic container.
--
--
-- > let xs = toMinLen [1,2,3] :: Maybe (MinLen (Succ Zero) [Int])
-- > xs
-- Just (MinLen {unMinLen = [1,2,3]})
--
-- > :i xs
-- xs :: Maybe (MinLen (Succ Zero) [Int])
--
--
-- -- > toMinLen [] :: Maybe (MinLen (Succ Zero) [Int]) -- Nothing --toMinLen :: (MonoFoldable mono, TypeNat nat) => mono -> Maybe (MinLen nat mono) -- | Unsafe -- -- Although this function itself cannot cause a segfault, it breaks the -- safety guarantees of MinLen and can lead to a segfault when -- using otherwise safe functions. -- --
-- > let xs = unsafeToMinLen [] :: MinLen (Succ Zero) [Int] -- > olength xs -- 0 -- > head xs -- *** Exception: Data.MonoTraversable.headEx: empty --unsafeToMinLen :: mono -> MinLen nat mono -- | Adds an element to the front of a list, increasing its minimum length -- by 1. -- --
-- > let xs = unsafeToMinLen [1,2,3] :: MinLen (Succ Zero) [Int]
-- > 0 `mlcons` xs
-- MinLen {unMinLen = [0,1,2,3]}
--
mlcons :: IsSequence seq => Element seq -> MinLen nat seq -> MinLen (Succ nat) seq
infixr 5 `mlcons`
-- | Concatenate two sequences, adding their minimum lengths together.
--
--
-- > let xs = unsafeToMinLen [1,2,3] :: MinLen (Succ Zero) [Int]
-- > xs `mlappend` xs
-- MinLen {unMinLen = [1,2,3,1,2,3]}
--
mlappend :: IsSequence seq => MinLen x seq -> MinLen y seq -> MinLen (AddNat x y) seq
-- | Joins two semigroups, keeping the larger MinLen of the two.
--
--
-- > let xs = unsafeToMinLen [1] :: MinLen (Succ Zero) [Int]
-- > let ys = xs `mlunion` xs
-- > ys
-- MinLen {unMinLen = [1,1]}
--
-- > :i ys
-- ys :: MinLen (Succ Zero) [Int]
--
mlunion :: (Semigroup mono, GrowingAppend mono) => MinLen x mono -> MinLen y mono -> MinLen (MaxNat x y) mono
-- | Return the first element of a monomorphic container.
--
-- Safe version of headEx, only works on monomorphic containers
-- wrapped in a MinLen (Succ nat).
head :: MonoFoldable mono => MinLen (Succ nat) mono -> Element mono
-- | Return the last element of a monomorphic container.
--
-- Safe version of lastEx, only works on monomorphic containers
-- wrapped in a MinLen (Succ nat).
last :: MonoFoldable mono => MinLen (Succ nat) mono -> Element mono
-- | Returns all but the first element of a sequence, reducing its
-- MinLen by 1.
--
-- Safe, only works on sequences wrapped in a MinLen
-- (Succ nat).
--
--
-- > let xs = toMinLen [1,2,3] :: Maybe (MinLen (Succ Zero) [Int])
-- > fmap tailML xs
-- Just (MinLen {unMinLen = [2,3]})
--
tailML :: IsSequence seq => MinLen (Succ nat) seq -> MinLen nat seq
-- | Returns all but the last element of a sequence, reducing its
-- MinLen by 1.
--
-- Safe, only works on sequences wrapped in a MinLen
-- (Succ nat).
--
--
-- > let xs = toMinLen [1,2,3] :: Maybe (MinLen (Succ Zero) [Int])
-- > fmap initML xs
-- Just (MinLen {unMinLen = [1,2]})
--
initML :: IsSequence seq => MinLen (Succ nat) seq -> MinLen nat seq
-- | Containers which, when two values are combined, the combined length is
-- no less than the larger of the two inputs. In code:
--
-- -- olength (x <> y) >= max (olength x) (olength y) ---- -- This class has no methods, and is simply used to assert that this law -- holds, in order to provide guarantees of correctness (see, for -- instance, Data.NonNull). -- -- This should have a Semigroup superclass constraint, however, -- due to Semigroup only recently moving to base, some packages -- do not provide instances. class MonoFoldable mono => GrowingAppend mono -- | Map each element of a monomorphic container to a semigroup, and -- combine the results. -- -- Safe version of ofoldMap1Ex, only works on monomorphic -- containers wrapped in a MinLen (Succ nat). -- --
-- > let xs = ("hello", 1 :: Integer) `mlcons` (" world", 2) `mlcons` (toMinLenZero [])
-- > ofoldMap1 fst xs
-- "hello world"
--
ofoldMap1 :: (MonoFoldable mono, Semigroup m) => (Element mono -> m) -> MinLen (Succ nat) mono -> m
-- | Join a monomorphic container, whose elements are Semigroups,
-- together.
--
-- Safe, only works on monomorphic containers wrapped in a
-- MinLen (Succ nat).
--
--
-- > let xs = "a" `mlcons` "b" `mlcons` "c" `mlcons` (toMinLenZero [])
-- > xs
-- MinLen {unMinLen = ["a","b","c"]}
--
-- > ofold1 xs
-- "abc"
--
ofold1 :: (MonoFoldable mono, Semigroup (Element mono)) => MinLen (Succ nat) mono -> Element mono
-- | Right-associative fold of a monomorphic container with no base
-- element.
--
-- Safe version of ofoldr1Ex, only works on monomorphic containers
-- wrapped in a MinLen (Succ nat).
--
-- -- foldr1 f = Prelude.foldr1 f . otoList ---- --
-- > let xs = "a" `mlcons` "b" `mlcons` "c" `mlcons` (toMinLenZero []) -- > ofoldr1 (++) xs -- "abc" --ofoldr1 :: MonoFoldable mono => (Element mono -> Element mono -> Element mono) -> MinLen (Succ nat) mono -> Element mono -- | Strict left-associative fold of a monomorphic container with no base -- element. -- -- Safe version of ofoldl1Ex', only works on monomorphic -- containers wrapped in a MinLen (Succ nat). -- --
-- foldl1' f = Prelude.foldl1' f . otoList ---- --
-- > let xs = "a" `mlcons` "b" `mlcons` "c" `mlcons` (toMinLenZero []) -- > ofoldl1' (++) xs -- "abc" --ofoldl1' :: MonoFoldable mono => (Element mono -> Element mono -> Element mono) -> MinLen (Succ nat) mono -> Element mono -- | Get the maximum element of a monomorphic container. -- -- Safe version of maximumEx, only works on monomorphic containers -- wrapped in a MinLen (Succ nat). -- --
-- > let xs = toMinLen [1,2,3] :: Maybe (MinLen (Succ Zero) [Int]) -- > fmap maximum xs -- Just 3 --maximum :: (MonoFoldable mono, Ord (Element mono)) => MinLen (Succ nat) mono -> Element mono -- | Get the minimum element of a monomorphic container. -- -- Safe version of minimumEx, only works on monomorphic containers -- wrapped in a MinLen (Succ nat). -- --
-- > let xs = toMinLen [1,2,3] :: Maybe (MinLen (Succ Zero) [Int]) -- > fmap minimum xs -- Just 1 --minimum :: (MonoFoldable mono, Ord (Element mono)) => MinLen (Succ nat) mono -> Element mono -- | Get the maximum element of a monomorphic container, using a supplied -- element ordering function. -- -- Safe version of maximumByEx, only works on monomorphic -- containers wrapped in a MinLen (Succ nat). maximumBy :: MonoFoldable mono => (Element mono -> Element mono -> Ordering) -> MinLen (Succ nat) mono -> Element mono -- | Get the minimum element of a monomorphic container, using a supplied -- element ordering function. -- -- Safe version of minimumByEx, only works on monomorphic -- containers wrapped in a MinLen (Succ nat). minimumBy :: MonoFoldable mono => (Element mono -> Element mono -> Ordering) -> MinLen (Succ nat) mono -> Element mono instance (Data.Data.Data nat, Data.Data.Data mono) => Data.Data.Data (Data.MinLen.MinLen nat mono) instance GHC.Show.Show mono => GHC.Show.Show (Data.MinLen.MinLen nat mono) instance GHC.Read.Read mono => GHC.Read.Read (Data.MinLen.MinLen nat mono) instance GHC.Classes.Ord mono => GHC.Classes.Ord (Data.MinLen.MinLen nat mono) instance GHC.Classes.Eq mono => GHC.Classes.Eq (Data.MinLen.MinLen nat mono) instance Data.MonoTraversable.MonoFunctor mono => Data.MonoTraversable.MonoFunctor (Data.MinLen.MinLen nat mono) instance Data.MonoTraversable.MonoFoldable mono => Data.MonoTraversable.MonoFoldable (Data.MinLen.MinLen nat mono) instance Data.MonoTraversable.GrowingAppend mono => Data.MonoTraversable.GrowingAppend (Data.MinLen.MinLen nat mono) instance Data.MinLen.TypeNat Data.MinLen.Zero instance Data.MinLen.TypeNat nat => Data.MinLen.TypeNat (Data.MinLen.Succ nat) instance Data.MonoTraversable.MonoTraversable mono => Data.MonoTraversable.MonoTraversable (Data.MinLen.MinLen nat mono) instance (Data.Semigroup.Semigroup mono, Data.MonoTraversable.GrowingAppend mono) => Data.Semigroup.Semigroup (Data.MinLen.MinLen nat mono) instance Data.Sequences.SemiSequence seq => Data.Sequences.SemiSequence (Data.MinLen.MinLen nat seq) instance Data.MonoTraversable.MonoPointed mono => Data.MonoTraversable.MonoPointed (Data.MinLen.MinLen Data.MinLen.Zero mono) instance Data.MonoTraversable.MonoPointed mono => Data.MonoTraversable.MonoPointed (Data.MinLen.MinLen (Data.MinLen.Succ Data.MinLen.Zero) mono) instance Data.Sequences.IsSequence mono => Data.MonoTraversable.MonoComonad (Data.MinLen.MinLen (Data.MinLen.Succ Data.MinLen.Zero) mono)