mono-traversable 0.9.1 → 0.9.2
raw patch · 5 files changed
+141/−12 lines, 5 filesdep ~comonadPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: comonad
API changes (from Hackage documentation)
+ Data.MinLen: instance IsSequence mono => MonoComonad (MinLen (Succ Zero) mono)
+ Data.MonoTraversable: class MonoFunctor mono => MonoComonad mono where oextract = extract oextend = extend
+ Data.MonoTraversable: instance (Comonad f, Comonad g) => MonoComonad (Coproduct f g a)
+ Data.MonoTraversable: instance (Comonad w, Monoid m) => MonoComonad (TracedT m w a)
+ Data.MonoTraversable: instance (Functor f, Functor g) => MonoFunctor (Coproduct f g a)
+ Data.MonoTraversable: instance Comonad w => MonoComonad (EnvT e w a)
+ Data.MonoTraversable: instance Comonad w => MonoComonad (IdentityT w a)
+ Data.MonoTraversable: instance Comonad w => MonoComonad (StoreT s w a)
+ Data.MonoTraversable: instance Functor w => MonoFunctor (EnvT e w a)
+ Data.MonoTraversable: instance Functor w => MonoFunctor (StoreT s w a)
+ Data.MonoTraversable: instance Functor w => MonoFunctor (TracedT m w a)
+ Data.MonoTraversable: instance MonoComonad (Arg a b)
+ Data.MonoTraversable: instance MonoComonad (Identity a)
+ Data.MonoTraversable: instance MonoComonad (NonEmpty a)
+ Data.MonoTraversable: instance MonoComonad (Tree a)
+ Data.MonoTraversable: instance MonoComonad (ViewL a)
+ Data.MonoTraversable: instance MonoComonad (ViewR a)
+ Data.MonoTraversable: instance MonoComonad (e, a)
+ Data.MonoTraversable: instance MonoFunctor (Arg a b)
+ Data.MonoTraversable: instance Monoid m => MonoComonad (m -> a)
+ Data.MonoTraversable: oextend :: MonoComonad mono => (mono -> Element mono) -> mono -> mono
+ Data.MonoTraversable: oextract :: MonoComonad mono => mono -> Element mono
Files
- ChangeLog.md +4/−0
- mono-traversable.cabal +2/−2
- src/Data/MinLen.hs +32/−1
- src/Data/MonoTraversable.hs +102/−8
- src/Data/Sequences.hs +1/−1
ChangeLog.md view
@@ -1,3 +1,7 @@+## 0.9.2++* MonoComonad+ ## 0.9.1 * Fill in missing Mono\* instances [#72](https://github.com/snoyberg/mono-traversable/pull/72)
mono-traversable.cabal view
@@ -1,5 +1,5 @@ name: mono-traversable-version: 0.9.1+version: 0.9.2 synopsis: Type classes for mapping, folding, and traversing monomorphic containers description: Monomorphic variants of the Functor, Foldable, and Traversable typeclasses. If you understand Haskell's basic typeclasses, you understand mono-traversable. In addition to what you are used to, it adds on an IsSequence typeclass and has code for marking data structures as non-empty. homepage: https://github.com/snoyberg/mono-traversable@@ -22,7 +22,7 @@ Data.MinLen Data.ByteVector other-modules: Data.GrowingAppend- build-depends: base >= 4 && < 5+ build-depends: base >= 4.5 && < 5 , containers >= 0.4 , unordered-containers >=0.2 , hashable
src/Data/MinLen.hs view
@@ -7,6 +7,7 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-} module Data.MinLen ( -- * Type level naturals -- ** Peano numbers@@ -40,7 +41,7 @@ , minimumBy ) where -import Prelude (Num (..), Maybe (..), Int, Ordering (..), Eq, Ord, Read, Show, Functor (..), ($), flip)+import Prelude (Num (..), Maybe (..), Int, Ordering (..), Eq, Ord (..), Read, Show, Functor (..), ($), flip, const, Bool (..), otherwise) import Data.Data (Data) import Data.Typeable (Typeable) import Control.Category@@ -50,6 +51,7 @@ import Data.Semigroup (Semigroup (..)) import Data.GrowingAppend import Control.Monad (liftM)+import Control.Monad.Trans.State.Strict (evalState, state) -- $peanoNumbers -- <https://wiki.haskell.org/Peano_numbers Peano numbers> are a simple way to@@ -480,3 +482,32 @@ -> Element mono minimumBy cmp = minimumByEx cmp . unMinLen {-# INLINE minimumBy #-}++-- | 'oextract' is 'head'.+--+-- For @'oextend' f@, the new 'mono' is populated by applying @f@ to+-- successive 'tail's of the original 'mono'.+--+-- For example, for @'MinLen' ('Succ' 'Zero') ['Int']@, or+-- @'NonNull' ['Int']@:+--+-- @+-- 'oextend' f [1,2,3,4,5] = [ f [1, 2, 3, 4, 5]+-- , f [2, 3, 4, 5]+-- , f [3, 4, 5]+-- , f [4, 5]+-- , f [5]+-- ]+-- @+--+-- Meant to be a direct analogy to the instance for 'NonEmpty' @a@.+--+instance IsSequence mono+ => MonoComonad (MinLen (Succ Zero) mono) where+ oextract = head+ oextend f (MinLen mono) = MinLen+ . flip evalState mono+ . ofor mono+ . const+ . state+ $ \mono' -> (f (MinLen mono'), tailEx mono')
src/Data/MonoTraversable.hs view
@@ -1,8 +1,9 @@-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ConstrainedClassMethods #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-} -- | Type classes mirroring standard typeclasses, but working with monomorphic containers. -- -- The motivation is that some commonly used data types (i.e., 'ByteString' and@@ -63,7 +64,11 @@ import Control.Monad.Trans.List (ListT) import Control.Monad.Trans.Identity (IdentityT) import Data.Functor.Apply (MaybeApply (..), WrappedApplicative)-import Control.Comonad (Cokleisli)+import Control.Comonad (Cokleisli, Comonad, extract, extend)+import Control.Comonad.Store (StoreT)+import Control.Comonad.Env (EnvT)+import Control.Comonad.Traced (TracedT)+import Data.Functor.Coproduct (Coproduct) import Control.Monad.Trans.Writer (WriterT) import qualified Control.Monad.Trans.Writer.Strict as Strict (WriterT) import Control.Monad.Trans.State (StateT(..))@@ -85,7 +90,7 @@ import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Storable as VS import qualified Data.IntSet as IntSet-import Data.Semigroup (Semigroup, Option (..))+import Data.Semigroup (Semigroup, Option (..), Arg) import qualified Data.ByteString.Unsafe as SU import Data.DList (DList) import qualified Data.DList as DL@@ -142,6 +147,11 @@ type instance Element (Static f a b) = b type instance Element (U.Vector a) = a type instance Element (VS.Vector a) = a+type instance Element (Arg a b) = b+type instance Element (EnvT e w a) = a+type instance Element (StoreT s w a) = a+type instance Element (TracedT m w a) = a+type instance Element (Coproduct f g a) = a -- | Monomorphic containers that can be mapped over. class MonoFunctor mono where@@ -184,6 +194,11 @@ instance MonoFunctor (Map k v) instance MonoFunctor (HashMap k v) instance MonoFunctor (Vector a)+instance MonoFunctor (Arg a b)+instance Functor w => MonoFunctor (EnvT e w a)+instance Functor w => MonoFunctor (StoreT s w a)+instance Functor w => MonoFunctor (TracedT m w a)+instance (Functor f, Functor g) => MonoFunctor (Coproduct f g a) instance Arrow a => MonoFunctor (WrappedArrow a b c) instance Functor f => MonoFunctor (MaybeApply f a) instance Functor f => MonoFunctor (WrappedApplicative f a)@@ -265,7 +280,10 @@ -- | Compare the length of a monomorphic container and a given number. ocompareLength :: Integral i => mono -> i -> Ordering- ocompareLength c0 i0 = olength c0 `compare` fromIntegral i0 -- FIXME more efficient implementation+ -- Basic implementation using length for most instance. See the list+ -- instance below for support for infinite structures. Arguably, that+ -- should be the default instead of this.+ ocompareLength c0 i0 = olength c0 `compare` fromIntegral i0 {-# INLINE ocompareLength #-} -- | Map each element of a monomorphic container to an action,@@ -542,6 +560,11 @@ instance MonoFoldable [a] where otoList = id {-# INLINE otoList #-}++ ocompareLength [] i = 0 `compare` i+ ocompareLength (_:xs) i+ | i Prelude.<= 0 = GT+ | otherwise = ocompareLength xs (i - 1) instance MonoFoldable (Maybe a) where omapM_ _ Nothing = return () omapM_ f (Just x) = f x@@ -1205,3 +1228,74 @@ instance MonoPointed (Tree a) where opoint a = Node a [] {-# INLINE opoint #-}+++-- | Typeclass for monomorphic containers where it is always okay to+-- "extract" a value from with 'oextract', and where you can extrapolate+-- any "extracting" function to be a function on the whole part with+-- 'oextend'.+--+-- 'oextend' and 'oextract' should work together following the laws:+--+-- @+-- 'oextend' 'oextract' = 'id'+-- 'oextract' . 'oextend' f = f+-- 'oextend' f . 'oextend' g = 'oextend' (f . 'oextend' g)+-- @+--+-- As an intuition, @'oextend' f@ uses @f@ to "build up" a new @mono@ with+-- pieces from the old one received by @f@.+--+class MonoFunctor mono => MonoComonad mono where+ -- | Extract an element from @mono@. Can be thought of as a dual+ -- concept to @opoint@.+ oextract :: mono -> Element mono+ -- | "Extend" a @mono -> 'Element' mono@ function to be a @mono ->+ -- mono@; that is, builds a new @mono@ from the old one by using pieces+ -- glimpsed from the given function.+ oextend :: (mono -> Element mono) -> mono -> mono++ default oextract :: (Comonad w, (w a) ~ mono, Element (w a) ~ a)+ => mono -> Element mono+ oextract = extract+ {-# INLINE oextract #-}+ default oextend :: (Comonad w, (w a) ~ mono, Element (w a) ~ a)+ => (mono -> Element mono) -> mono -> mono+ oextend = extend+ {-# INLINE oextend #-}++-- Comonad+instance MonoComonad (Tree a)+instance MonoComonad (NonEmpty a)+instance MonoComonad (Identity a)+instance Monoid m => MonoComonad (m -> a)+instance MonoComonad (e, a)+instance MonoComonad (Arg a b)+instance Comonad w => MonoComonad (IdentityT w a)+instance Comonad w => MonoComonad (EnvT e w a)+instance Comonad w => MonoComonad (StoreT s w a)+instance (Comonad w, Monoid m) => MonoComonad (TracedT m w a)+instance (Comonad f, Comonad g) => MonoComonad (Coproduct f g a)++-- Not Comonad+instance MonoComonad (ViewL a) where+ oextract ~(x :< _) = x+ {-# INLINE oextract #-}+ oextend f w@ ~(_ :< xxs) =+ f w :< case Seq.viewl xxs of+ EmptyL -> Seq.empty+ xs -> case oextend f xs of+ EmptyL -> Seq.empty+ y :< ys -> y Seq.<| ys++instance MonoComonad (ViewR a) where+ oextract ~(_ :> x) = x+ {-# INLINE oextract #-}+ oextend f w@ ~(xxs :> _) =+ (case Seq.viewr xxs of+ EmptyR -> Seq.empty+ xs -> case oextend f xs of+ EmptyR -> Seq.empty+ ys :> y -> ys Seq.|> y+ ) :> f w+
src/Data/Sequences.hs view
@@ -1531,7 +1531,7 @@ -- | Same as @sortBy . comparing@. ----- Sicne 0.7.0+-- Since 0.7.0 sortOn :: (Ord o, SemiSequence seq) => (Element seq -> o) -> seq -> seq sortOn = sortBy . comparing {-# INLINE sortOn #-}