packages feed

nonempty-alternative (empty) → 0.3.0

raw patch · 4 files changed

+220/−0 lines, 4 filesdep +basedep +comonaddep +semigroupssetup-changed

Dependencies added: base, comonad, semigroups

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright guaraqe (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of guaraqe nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ nonempty-alternative.cabal view
@@ -0,0 +1,25 @@+name:                nonempty-alternative+version:             0.3.0+synopsis:            NonEmpty for Alternative types+description:         Please see README.md+homepage:            http://github.com/guaraqe/nonempty-alternative#readme+license:             BSD3+license-file:        LICENSE+author:              guaraqe+maintainer:          guaraqe@openmailbox.org+copyright:           2016 guaraqe+category:            Data+build-type:          Simple+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     Data.NonEmpty+  build-depends:       base >= 4.7 && < 5+                     , semigroups >= 0.18+                     , comonad >= 4.2+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/guaraqe/nonempty-alternative
+ src/Data/NonEmpty.hs view
@@ -0,0 +1,163 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric #-}++module Data.NonEmpty+       (+       -- * The type of left non-empty alternatives+         NonEmptyL (..)+       -- * Basic functions for `NonEmptyL`+       , headL+       , tailL+       , flattenL+       , joinL+       , budgeL+       -- * The type of right non-empty alternatives+       , NonEmptyR (..)+       -- * Basic functions for `NonEmptyR`+       , lastR+       , initR+       , flattenR+       , joinR+       , budgeR+       ) where++import Prelude hiding (head, tail)+import Data.Data+import GHC.Generics++import Data.Foldable+import Data.Semigroup+import Control.Applicative+import Control.Comonad++----------------------------------------------------------------------++-- | 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+  deriving (Show, Eq, Ord,Read, Data, Typeable, Generic, Generic1)++infixr 5 :<++-- | The `R`ight one is well suited for `snoc` structures.+data NonEmptyR f a = f a :> a+  deriving (Show, Eq, Ord,Read, Data, Typeable, Generic, Generic1)++infixl 5 :>++----------------------------------------------------------------------++instance Functor f => Functor (NonEmptyL f) where+  fmap f (x :< xs) = (f x) :< (f <$> xs)++instance Functor f => Functor (NonEmptyR f) where+  fmap f (xs :> x) = (f <$> xs) :> (f x)++----------------------------------------------------------------------++instance Alternative f => Applicative (NonEmptyL f) where+  pure x = x :< empty++  (f :< fs) <*> (x :< xs) = (f x) :< (   (pure f <*> xs    )+                                     <|> (fs     <*> (pure x <|> xs)))++instance Alternative f => Applicative (NonEmptyR f) where+  pure x = empty :> 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+                        zs = xs >>= flattenL . f++----------------------------------------------------------------------++instance Alternative f => Comonad (NonEmptyL f) where+  extract = headL+  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)++----------------------------------------------------------------------++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+                          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++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+                          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 xs++instance (Functor f, Traversable f) => Traversable (NonEmptyR f) where+  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)++instance Alternative f => Semigroup (NonEmptyR f a) where+  (xs :> x) <> (ys :> y) = (xs <|> pure x <|> ys) :> y++----------------------------------------------------------------------++headL :: NonEmptyL f a -> a+headL (x :< _) = x++tailL :: NonEmptyL f a -> f a+tailL (_ :< xs) = xs++flattenL :: Alternative f => NonEmptyL f a -> f a+flattenL (x :< xs) = pure x <|> xs++joinL :: (Alternative f, Monad f)+      => NonEmptyL f (NonEmptyL f a) -> NonEmptyL f a+joinL ((x :< xs) :< ys) = x :< (xs <|> (ys >>= flattenL))++budgeL :: (Alternative f, Alternative g)+       => NonEmptyL f (g a) -> NonEmptyL f (g a)+budgeL = (empty :<) . flattenL++lastR :: NonEmptyR f a -> a+lastR (_ :> x) = x++initR :: NonEmptyR f a -> f a+initR (xs :> _) = xs++flattenR :: Alternative f => NonEmptyR f a -> f a+flattenR (xs :> x) = xs <|> pure x++joinR :: (Alternative f, Monad f)+      => NonEmptyR f (NonEmptyR f a) -> NonEmptyR f a+joinR (ys :> (xs :> x)) = ((ys >>= flattenR) <|> xs) :> x++budgeR :: (Alternative f, Alternative g)+       => NonEmptyR f (g a) -> NonEmptyR f (g a)+budgeR = (:> empty) . flattenR