semigroups 0.12.2 → 0.13
raw patch · 4 files changed
+153/−52 lines, 4 filesdep ~base
Dependency ranges changed: base
Files
- LICENSE +1/−1
- semigroups.cabal +5/−2
- src/Data/List/NonEmpty.hs +4/−35
- src/Data/Semigroup.hs +143/−14
LICENSE view
@@ -1,4 +1,4 @@-Copyright 2011-2013 Edward Kmett+Copyright 2011-2014 Edward Kmett All rights reserved.
semigroups.cabal view
@@ -1,6 +1,6 @@ name: semigroups category: Algebra, Data, Data Structures, Math-version: 0.12.2+version: 0.13 license: BSD3 cabal-version: >= 1.10 license-file: LICENSE@@ -9,7 +9,7 @@ stability: provisional homepage: http://github.com/ekmett/semigroups/ bug-reports: http://github.com/ekmett/semigroups/issues-copyright: Copyright (C) 2011-2013 Edward A. Kmett+copyright: Copyright (C) 2011-2014 Edward A. Kmett synopsis: Anything that associates description: In mathematics, a semigroup is an algebraic structure consisting of a set together with an associative binary operation. A semigroup generalizes a monoid in that there might not exist an identity element. It also (originally) generalized a group (a monoid with all inverses) to a type where every element did not have to have an inverse, thus the name semigroup.@@ -31,6 +31,9 @@ if !impl(hugs) other-extensions: DeriveDataTypeable cpp-options: -DLANGUAGE_DeriveDataTypeable++ if impl(ghc >= 7.4)+ cpp-options: -DLANGUAGE_DeriveGeneric if flag(base2) build-depends: base == 2.*
src/Data/List/NonEmpty.hs view
@@ -5,7 +5,7 @@ ----------------------------------------------------------------------------- -- | -- Module : Data.List.NonEmpty--- Copyright : (C) 2011-2013 Edward Kmett,+-- Copyright : (C) 2011-2014 Edward Kmett, -- (C) 2010 Tony Morris, Oliver Taylor, Eelis van der Weegen -- License : BSD-style (see the file LICENSE) --@@ -172,22 +172,6 @@ b <$ ~(_ :| as) = b :| (b <$ as) #endif -{--instance Extend NonEmpty where- extend f w@ ~(_ :| aas) = f w :| case aas of- [] -> []- (a:as) -> toList (extend f (a :| as))--instance Comonad NonEmpty where- extract ~(a :| _) = a--instance Apply NonEmpty where- (<.>) = ap--instance Alt NonEmpty where- (a :| as) <!> ~(b :| bs) = a :| (as ++ b : bs)--}- instance Applicative NonEmpty where pure a = a :| [] (<*>) = ap@@ -201,12 +185,6 @@ instance Traversable NonEmpty where traverse f ~(a :| as) = (:|) <$> f a <*> traverse f as -{--instance Traversable1 NonEmpty where- traverse1 f (a :| []) = (:|[]) <$> f a- traverse1 f (a :| (b: bs)) = (\a' (b':| bs') -> a' :| b': bs') <$> f a <.> traverse1 f (b :| bs)--}- instance Foldable NonEmpty where foldr f z ~(a :| as) = f a (foldr f z as) foldl f z ~(a :| as) = foldl f (f z a) as@@ -214,15 +192,6 @@ foldMap f ~(a :| as) = f a `mappend` foldMap f as fold ~(m :| ms) = m `mappend` fold ms -{--instance Foldable1 NonEmpty where- foldMap1 f (a :| []) = f a- foldMap1 f (a :| b : bs) = f a <> foldMap1 f (b :| bs)--instance Semigroup (NonEmpty a) where- (<>) = (<!>)--}- -- | Extract the first element of the stream. head :: NonEmpty a -> a head ~(a :| _) = a@@ -547,7 +516,7 @@ nubBy :: (a -> a -> Bool) -> NonEmpty a -> NonEmpty a nubBy eq (a :| as) = a :| List.nubBy eq (List.filter (\b -> not (eq a b)) as) --- | 'transpose' for NonEmtpy, behaves the same as 'Data.List.transpose'+-- | 'transpose' for 'NonEmpty', behaves the same as 'Data.List.transpose' -- The rows/columns need not be the same length, in which case -- > transpose . transpose /= id transpose :: NonEmpty (NonEmpty a) -> NonEmpty (NonEmpty a)@@ -555,11 +524,11 @@ . fromList . List.transpose . Foldable.toList . fmap Foldable.toList --- | 'sortBy' for NonEmtpy, behaves the same as 'Data.List.sortBy'+-- | 'sortBy' for 'NonEmpty', behaves the same as 'Data.List.sortBy' sortBy :: (a -> a -> Ordering) -> NonEmpty a -> NonEmpty a sortBy f = lift (List.sortBy f) --- | 'sortOn' for NonEmtpy, behaves the same as:+-- | 'sortOn' for 'NonEmpty', behaves the same as: -- -- > sortBy . comparing sortOn :: Ord o => (a -> o) -> NonEmpty a -> NonEmpty a
src/Data/Semigroup.hs view
@@ -2,6 +2,10 @@ #ifdef LANGUAGE_DeriveDataTypeable {-# LANGUAGE DeriveDataTypeable #-} #endif+#ifdef LANGUAGE_DeriveGeneric+{-# LANGUAGE DeriveGeneric #-}+#endif+{-# LANGUAGE GeneralizedNewtypeDeriving #-} #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE Trustworthy #-}@@ -9,7 +13,7 @@ ----------------------------------------------------------------------------- -- | -- Module : Data.Semigroup--- Copyright : (C) 2011-2013 Edward Kmett,+-- Copyright : (C) 2011-2014 Edward Kmett -- License : BSD-style (see the file LICENSE) -- -- Maintainer : Edward Kmett <ekmett@gmail.com>@@ -86,17 +90,24 @@ #ifdef LANGUAGE_DeriveDataTypeable import Data.Data #endif+#ifdef LANGUAGE_DeriveGeneric+import GHC.Generics+#endif infixr 6 <> class Semigroup a where -- | An associative operation. --- -- > (a <> b) <> c = a <> (b <> c)+ -- @+ -- (a '<>' b) '<>' c = a '<>' (b '<>' c)+ -- @ -- -- If @a@ is also a 'Monoid' we further require --- -- > (<>) = mappend+ -- @+ -- ('<>') = 'mappend'+ -- @ (<>) :: a -> a -> a #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702 default (<>) :: Monoid a => a -> a -> a@@ -114,12 +125,14 @@ -- | Repeat a value (n + 1) times. --- -- > times1p n a = a <> a <> ... <> a -- using <> n times+ -- @+ -- 'times1p' n a = a '<>' a '<>' ... '<>' a -- using '<>' n times+ -- @ -- -- The default definition uses peasant multiplication, exploiting associativity to only -- require /O(log n)/ uses of @\<\>@. --- -- See also 'times'.+ -- See also 'timesN'. times1p :: Whole n => n -> a -> a times1p y0 x0 = f x0 (1 Prelude.+ y0)@@ -224,7 +237,8 @@ (a :| as) <> ~(b :| bs) = a :| (as ++ b : bs) newtype Min a = Min { getMin :: a } deriving- ( Eq, Ord, Bounded, Show, Read+ ( Eq, Ord, Enum, Bounded, Show, Read+ , Hashable #ifdef LANGUAGE_DeriveDataTypeable , Data, Typeable #endif@@ -238,11 +252,38 @@ mempty = maxBound mappend = (<>) +instance Functor Min where+ fmap f (Min x) = Min (f x)++instance Foldable Min where+ foldMap f (Min a) = f a++instance Traversable Min where+ traverse f (Min a) = Min <$> f a++instance Applicative Min where+ pure = Min+ a <* _ = a+ _ *> a = a+ Min f <*> Min x = Min (f x)++instance Monad Min where+ return = Min+ _ >> a = a+ Min a >>= f = f a++instance MonadFix Min where+ mfix f = fix (f . getMin)+ newtype Max a = Max { getMax :: a } deriving- ( Eq, Ord, Bounded, Show, Read+ ( Eq, Ord, Enum, Bounded, Show, Read+ , Hashable #ifdef LANGUAGE_DeriveDataTypeable , Data, Typeable #endif+#ifdef LANGUAGE_DeriveGeneric+ , Generic+#endif ) instance Ord a => Semigroup (Max a) where@@ -253,31 +294,109 @@ mempty = minBound mappend = (<>) +instance Functor Max where+ fmap f (Max x) = Max (f x)++instance Foldable Max where+ foldMap f (Max a) = f a++instance Traversable Max where+ traverse f (Max a) = Max <$> f a++instance Applicative Max where+ pure = Max+ a <* _ = a+ _ *> a = a+ Max f <*> Max x = Max (f x)++instance Monad Max where+ return = Max+ _ >> a = a+ Max a >>= f = f a++instance MonadFix Max where+ mfix f = fix (f . getMax)+ -- | Use @'Option' ('First' a)@ to get the behavior of 'Data.Monoid.First' from @Data.Monoid@. newtype First a = First { getFirst :: a } deriving- ( Eq, Ord, Bounded, Show, Read+ ( Eq, Ord, Enum, Bounded, Show, Read+ , Hashable #ifdef LANGUAGE_DeriveDataTypeable , Data , Typeable #endif+#ifdef LANGUAGE_DeriveGeneric+ , Generic+#endif ) instance Semigroup (First a) where a <> _ = a times1p _ a = a +instance Functor First where+ fmap f (First x) = First (f x)++instance Foldable First where+ foldMap f (First a) = f a++instance Traversable First where+ traverse f (First a) = First <$> f a++instance Applicative First where+ pure x = First x+ a <* _ = a+ _ *> a = a+ First f <*> First x = First (f x)++instance Monad First where+ return = First+ _ >> a = a+ First a >>= f = f a++instance MonadFix First where+ mfix f = fix (f . getFirst)+ -- | Use @'Option' ('Last' a)@ to get the behavior of 'Data.Monoid.Last' from @Data.Monoid@ newtype Last a = Last { getLast :: a } deriving- ( Eq, Ord, Bounded, Show, Read+ ( Eq, Ord, Enum, Bounded, Show, Read+ , Hashable #ifdef LANGUAGE_DeriveDataTypeable , Data, Typeable #endif+#ifdef LANGUAGE_DeriveGeneric+ , Generic+#endif ) instance Semigroup (Last a) where _ <> b = b times1p _ a = a +instance Functor Last where+ fmap f (Last x) = Last (f x)+ a <$ _ = Last a++instance Foldable Last where+ foldMap f (Last a) = f a++instance Traversable Last where+ traverse f (Last a) = Last <$> f a++instance Applicative Last where+ pure = Last+ a <* _ = a+ _ *> a = a+ Last f <*> Last x = Last (f x)++instance Monad Last where+ return = Last+ _ >> a = a+ Last a >>= f = f a++instance MonadFix Last where+ mfix f = fix (f . getLast)+ -- (==)/XNOR on Bool forms a 'Semigroup', but has no good name #ifndef BASE2@@ -304,10 +423,14 @@ -- | Provide a Semigroup for an arbitrary Monoid. newtype WrappedMonoid m = WrapMonoid { unwrapMonoid :: m } deriving- ( Eq, Ord, Bounded, Show, Read+ ( Eq, Ord, Enum, Bounded, Show, Read+ , Hashable #ifdef LANGUAGE_DeriveDataTypeable , Data, Typeable #endif+#ifdef LANGUAGE_DeriveGeneric+ , Generic+#endif ) instance Monoid m => Semigroup (WrappedMonoid m) where@@ -319,7 +442,7 @@ -- | Repeat a value @n@ times. ----- > times n a = a <> a <> ... <> a -- using <> (n-1) times+-- > timesN n a = a <> a <> ... <> a -- using <> (n-1) times -- -- Implemented using 'times1p'. timesN :: (Whole n, Monoid a) => n -> a -> a@@ -328,14 +451,20 @@ {-# INLINE timesN #-} --- | Option is effectively 'Maybe' with a better instance of 'Monoid', built off of an underlying 'Semigroup'--- instead of an underlying 'Monoid'. Ideally, this type would not exist at all and we would just fix the 'Monoid' intance of 'Maybe'+-- | 'Option' is effectively 'Maybe' with a better instance of 'Monoid', built off of an underlying 'Semigroup'+-- instead of an underlying 'Monoid'.+--+-- Ideally, this type would not exist at all and we would just fix the 'Monoid' instance of 'Maybe' newtype Option a = Option { getOption :: Maybe a } deriving ( Eq, Ord, Show, Read+ , Hashable #ifdef LANGUAGE_DeriveDataTypeable , Data, Typeable #endif+#ifdef LANGUAGE_DeriveGeneric+ , Generic+#endif ) instance Functor Option where@@ -385,7 +514,7 @@ mempty = Option Nothing Option a `mappend` Option b = Option (a <> b) --- | This lets you use a difference list of a Semigroup as a Monoid.+-- | This lets you use a difference list of a 'Semigroup' as a 'Monoid'. diff :: Semigroup m => m -> Endo m diff = Endo . (<>)