packages feed

nonempty-alternative 0.3.0 → 0.4.0

raw patch · 2 files changed

+84/−50 lines, 2 files

Files

nonempty-alternative.cabal view
@@ -1,7 +1,8 @@ name:                nonempty-alternative-version:             0.3.0+version:             0.4.0 synopsis:            NonEmpty for Alternative types-description:         Please see README.md+description:         This package extends @NonEmpty@ from @semigroups@ for+                     arbitrary @Alternative@ types. homepage:            http://github.com/guaraqe/nonempty-alternative#readme license:             BSD3 license-file:        LICENSE
src/Data/NonEmpty.hs view
@@ -1,9 +1,29 @@+{-| This package extends @NonEmpty@ from @semigroups@ to arbitrary+@Alternative@ types. The method is the same as for lists, by+separating an element from the rest.++There are two natural ways to merge an element @x@ to the rest of the+structure @xs@. The first gives rise to @NonEmptyL@:++> flattenL :: NonEmptyL f a -> f a+> flattenL (x :<: xs) = pure x <|> xs++The second gives rise to @NonEmptyR@:++> flattenR :: NonEmptyR f a -> f a+> flattenR (xs :>: x) = xs <|> pure x++The instances are made so that @flattenL@ gives a type class morphism+between @NonEmptyL List@ and @List@, and @flattenR@ gives the same for+@NonEmptyR RList@ and @RList@ from the package @rlist@.+-}+ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-}  module Data.NonEmpty        (-       -- * The type of left non-empty alternatives+       -- * Left Non-Empty Alternatives          NonEmptyL (..)        -- * Basic functions for `NonEmptyL`        , headL@@ -11,7 +31,7 @@        , flattenL        , joinL        , budgeL-       -- * The type of right non-empty alternatives+       -- * Right Non-Empty Alternatives        , NonEmptyR (..)        -- * Basic functions for `NonEmptyR`        , lastR@@ -32,132 +52,145 @@  ---------------------------------------------------------------------- --- | NonEmptyL is naturally extended from `List` to any `Alternative`--- type in two different ways. They are differentiated by their--- instances.--- The `L`eft one is well suited for `cons` structures.-data NonEmptyL f a = a :< f a+-- | The type @NonEmptyL@ is well suited for `cons` structures.+data NonEmptyL f a = a :<: f a   deriving (Show, Eq, Ord,Read, Data, Typeable, Generic, Generic1) -infixr 5 :<+infixr 5 :<: --- | The `R`ight one is well suited for `snoc` structures.-data NonEmptyR f a = f a :> a+-- | The type @NonEmptyR@ is well suited for `snoc` structures.+data NonEmptyR f a = f a :>: a   deriving (Show, Eq, Ord,Read, Data, Typeable, Generic, Generic1) -infixl 5 :>+infixl 5 :>:  ----------------------------------------------------------------------  instance Functor f => Functor (NonEmptyL f) where-  fmap f (x :< xs) = (f x) :< (f <$> xs)+  fmap f (x :<: xs) = (f x) :<: (f <$> xs)  instance Functor f => Functor (NonEmptyR f) where-  fmap f (xs :> x) = (f <$> xs) :> (f x)+  fmap f (xs :>: x) = (f <$> xs) :>: (f x)  ----------------------------------------------------------------------  instance Alternative f => Applicative (NonEmptyL f) where-  pure x = x :< empty+  pure x = x :<: empty -  (f :< fs) <*> (x :< xs) = (f x) :< (   (pure f <*> xs    )+  (f :<: fs) <*> (x :<: xs) = (f x) :<: (   (pure f <*> xs    )                                      <|> (fs     <*> (pure x <|> xs)))  instance Alternative f => Applicative (NonEmptyR f) where-  pure x = empty :> x+  pure x = empty :>: x -  (fs :> f) <*> (xs :> x) = (   (fs     <*> (xs <|> pure x) )-                            <|> (pure f <*> xs    ) ) :> (f x)+  (fs :>: f) <*> (xs :>: x) = (   (fs     <*> (xs <|> pure x) )+                            <|> (pure f <*> xs    ) ) :>: (f x)  ----------------------------------------------------------------------  instance (Alternative f, Monad f) => Monad (NonEmptyL f) where-  (x :< xs) >>= f = y :< (ys <|> zs)-                  where (y :< ys) = f x+  (x :<: xs) >>= f = y :<: (ys <|> zs)+                  where (y :<: ys) = f x                         zs = xs >>= flattenL . f  ----------------------------------------------------------------------  instance Alternative f => Comonad (NonEmptyL f) where   extract = headL-  duplicate (x :< xs) = (x :< xs) :< (fmap (:< empty) xs)+  duplicate (x :<: xs) = (x :<: xs) :<: (fmap (:<: empty) xs)  instance Alternative f => Comonad (NonEmptyR f) where   extract = lastR-  duplicate (xs :> x) = (fmap (empty :>) xs) :> (xs :> x)+  duplicate (xs :>: x) = (fmap (empty :>:) xs) :>: (xs :>: x)  ----------------------------------------------------------------------  instance Foldable f => Foldable (NonEmptyL f) where-  foldr f z (x :< xs) = f x (foldr f z xs)-  foldr' f z (x :< xs) = f x (foldr' f z xs)-  foldr1 f (x :< xs) = if null xs+  foldr f z (x :<: xs) = f x (foldr f z xs)+  foldr' f z (x :<: xs) = f x (foldr' f z xs)+  foldr1 f (x :<: xs) = if null xs                           then x                           else f x (foldr1 f xs)-  foldl f z (x :< xs) = foldl f (f z x) xs-  foldl' f z (x :< xs) = foldl' f (f z x) xs-  foldl1 f (x :< xs) = foldl f x xs+  foldl f z (x :<: xs) = foldl f (f z x) xs+  foldl' f z (x :<: xs) = foldl' f (f z x) xs+  foldl1 f (x :<: xs) = foldl f x xs  instance Foldable f => Foldable (NonEmptyR f) where-  foldr f z (xs :> x) = foldr f (f x z) xs-  foldr' f z (xs :> x) = foldr' f (f x z) xs-  foldr1 f (xs :> x) = foldr f x xs-  foldl f z (xs :> x) = f (foldl f z xs) x-  foldl' f z (xs :> x) = f (foldl' f z xs) x-  foldl1 f (xs :> x) = if null xs+  foldr f z (xs :>: x) = foldr f (f x z) xs+  foldr' f z (xs :>: x) = foldr' f (f x z) xs+  foldr1 f (xs :>: x) = foldr f x xs+  foldl f z (xs :>: x) = f (foldl f z xs) x+  foldl' f z (xs :>: x) = f (foldl' f z xs) x+  foldl1 f (xs :>: x) = if null xs                           then x                           else f (foldl1 f xs) x  ----------------------------------------------------------------------  instance (Functor f, Traversable f) => Traversable (NonEmptyL f) where-  traverse f (x :< xs) = (:<) <$> f x+  traverse f (x :<: xs) = (:<:) <$> f x                               <*> traverse f xs  instance (Functor f, Traversable f) => Traversable (NonEmptyR f) where-  traverse f (xs :> x) = (:>) <$> traverse f xs+  traverse f (xs :>: x) = (:>:) <$> traverse f xs                               <*> f x  ----------------------------------------------------------------------  instance Alternative f => Semigroup (NonEmptyL f a) where-  (x :< xs) <> (y :< ys) = x :< (xs <|> pure y <|> ys)+  (x :<: xs) <> (y :<: ys) = x :<: (xs <|> pure y <|> ys)  instance Alternative f => Semigroup (NonEmptyR f a) where-  (xs :> x) <> (ys :> y) = (xs <|> pure x <|> ys) :> y+  (xs :>: x) <> (ys :>: y) = (xs <|> pure x <|> ys) :>: y  ---------------------------------------------------------------------- +-- | Extracts the structure's singular element. This function is total+-- and equivalent to @extract@ from @Comonad@. headL :: NonEmptyL f a -> a-headL (x :< _) = x+headL (x :<: _) = x +-- | Extracts the structure's remaining data. This function is total. tailL :: NonEmptyL f a -> f a-tailL (_ :< xs) = xs+tailL (_ :<: xs) = xs +-- | Flattens the structure to its base type from the left. flattenL :: Alternative f => NonEmptyL f a -> f a-flattenL (x :< xs) = pure x <|> xs+flattenL (x :<: xs) = pure x <|> xs +-- | This is equivalent to @join@ for @Monad@. joinL :: (Alternative f, Monad f)       => NonEmptyL f (NonEmptyL f a) -> NonEmptyL f a-joinL ((x :< xs) :< ys) = x :< (xs <|> (ys >>= flattenL))+joinL ((x :<: xs) :<: ys) = x :<: (xs <|> (ys >>= flattenL)) +-- | Budge the head into the remaining structure from the left, adding+-- an empty head. budgeL :: (Alternative f, Alternative g)        => NonEmptyL f (g a) -> NonEmptyL f (g a)-budgeL = (empty :<) . flattenL+budgeL = (empty :<:) . flattenL +----------------------------------------------------------------------++-- | Extracts the structure's singular element. This function is total+-- and equivalent to @extract@ from @Comonad@. lastR :: NonEmptyR f a -> a-lastR (_ :> x) = x+lastR (_ :>: x) = x +-- | Extracts the structure's remaining data. This function is total. initR :: NonEmptyR f a -> f a-initR (xs :> _) = xs+initR (xs :>: _) = xs +-- | Flattens the structure to its base type from the right. flattenR :: Alternative f => NonEmptyR f a -> f a-flattenR (xs :> x) = xs <|> pure x+flattenR (xs :>: x) = xs <|> pure x +-- | This is equivalent to @join@ for @Monad@. joinR :: (Alternative f, Monad f)       => NonEmptyR f (NonEmptyR f a) -> NonEmptyR f a-joinR (ys :> (xs :> x)) = ((ys >>= flattenR) <|> xs) :> x+joinR (ys :>: (xs :>: x)) = ((ys >>= flattenR) <|> xs) :>: x +-- | Budge the head into the remaining structure from the right,+-- adding an empty head. budgeR :: (Alternative f, Alternative g)        => NonEmptyR f (g a) -> NonEmptyR f (g a)-budgeR = (:> empty) . flattenR+budgeR = (:>: empty) . flattenR