separated 0.1.0 → 0.1.1
raw patch · 7 files changed
+141/−320 lines, 7 filesdep +papadep +parsecdep ~base
Dependencies added: papa, parsec
Dependency ranges changed: base
Files
- changelog +6/−2
- separated.cabal +8/−8
- src/Data/Separated.hs +0/−2
- src/Data/Separated/FlipSeparated.hs +0/−203
- src/Data/Separated/FlipSeparatedCons.hs +0/−18
- src/Data/Separated/Separated.hs +124/−84
- src/Data/Separated/SeparatedCons.hs +3/−3
changelog view
@@ -1,8 +1,12 @@+0.1.1++* Introduce `separatedBy` and `separatedBy1` combinators.+ 0.1.0 -Refactor and reorganisation of modules.+* Refactor and reorganisation of modules. 0.0.8 -This change log starts.+* This change log starts.
separated.cabal view
@@ -1,22 +1,22 @@ name: separated-version: 0.1.0+version: 0.1.1 license: BSD3 license-File: etc/LICENCE author: Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ> maintainer: Tony Morris-copyright: Copyright (C) 2013-2014 Tony Morris+copyright: Copyright (c) 2016, Commonwealth Scientific and Industrial Research Organisation (CSIRO) ABN 41 687 119 230. synopsis: A data type with elements separated by values category: Data description: A data type with elements separated by values-homepage: https://github.com/tonymorris/separated-bug-reports: https://github.com/tonymorris/separated/issues+homepage: https://github.com/data61/separated+bug-reports: https://github.com/data61/separated/issues cabal-version: >= 1.10 build-type: Custom extra-source-files: changelog source-repository head type: git- location: git@github.com:tonymorris/separated.git+ location: git@github.com:data61/separated.git flag small_base description: Choose the new, split-up base package.@@ -31,7 +31,8 @@ , semigroups >= 0.9 , semigroupoids >= 4.0 , bifunctors >= 4.0-+ , papa+ ghc-options: -Wall @@ -43,8 +44,6 @@ exposed-modules: Data.Separated- Data.Separated.FlipSeparated- Data.Separated.FlipSeparatedCons Data.Separated.Separated Data.Separated.SeparatedCons @@ -65,6 +64,7 @@ , directory >= 1.1 , QuickCheck >= 2.0 , template-haskell >= 2.8+ , parsec >= 3.1 ghc-options: -Wall
src/Data/Separated.hs view
@@ -4,7 +4,5 @@ module S ) where -import Data.Separated.FlipSeparated as S-import Data.Separated.FlipSeparatedCons as S import Data.Separated.Separated as S import Data.Separated.SeparatedCons as S
− src/Data/Separated/FlipSeparated.hs
@@ -1,203 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE MultiParamTypeClasses #-}--module Data.Separated.FlipSeparated(- FlipSeparated-, flipSeparated-, flipSeparated1-, fempty-) where--import Control.Applicative(Applicative(pure, (<*>)))-import Control.Category(Category(id, (.)))-import Control.Lens.Getter((^.))-import Control.Lens.Iso(Iso, iso)-import Control.Lens.Review((#))-import Data.Bifunctor(Bifunctor(bimap))-import Data.Eq(Eq)-import Data.Functor(Functor(fmap))-import Data.Functor.Apply(Apply((<.>)))-import Data.List(zipWith)-import Data.Monoid(Monoid(mappend, mempty))-import Data.Ord(Ord)-import Data.Semigroup(Semigroup((<>)))-import Data.Separated.FlipSeparatedCons(FlipSeparatedCons(FlipSeparatedConsF, FlipSeparatedConsG, (+.)))-import Data.Separated.Separated(Separated, Separated1, separated, separated1, separatedSwap, empty)-import Data.Separated.SeparatedCons((+:))-import Prelude(Show(show))---- $setup--- >>> :set -XNoImplicitPrelude--- >>> import Control.Monad(Monad(return))--- >>> import Data.Char(toUpper)--- >>> import Data.Int(Int)--- >>> import Data.Eq(Eq((==)))--- >>> import Data.List(reverse, drop)--- >>> import Data.Separated.Separated(empty, single)--- >>> import Data.String(String)--- >>> import Prelude(Num((+)))--- >>> import Test.QuickCheck(Arbitrary(..))--- >>> instance (Arbitrary s, Arbitrary a) => Arbitrary (Separated s a) where arbitrary = fmap (^. separated) arbitrary--- >>> instance (Arbitrary a, Arbitrary s) => Arbitrary (Separated1 s a) where arbitrary = do a <- arbitrary; x <- arbitrary; return ((a, x) ^. separated1)--- >>> instance (Arbitrary s, Arbitrary a) => Arbitrary (FlipSeparated a s) where arbitrary = fmap FlipSeparated arbitrary--- >>> instance (Arbitrary a, Arbitrary s) => Arbitrary (FlipSeparated1 s a) where arbitrary = do a <- arbitrary; return (FlipSeparated1 a)--newtype FlipSeparated a s =- FlipSeparated (Separated s a)- deriving (Eq, Ord)--instance Bifunctor FlipSeparated where- bimap f g (FlipSeparated x) =- FlipSeparated (bimap g f x)---- | Map across a @FlipSeparated@ on the separator values.------ prop> fmap id (x :: FlipSeparated Int String) == x------ prop> fmap (+1) (a +. b +. fempty) == (1+a) +. b +. fempty-instance Functor (FlipSeparated a) where- fmap =- bimap id---- | Applies functions with separator values, using a zipping operation,--- appending elements.------ >>> (fempty :: FlipSeparated [Int] (String -> [String])) <.> fempty--- []------ >>> (\s -> [s, reverse s, drop 1 s]) +. [1,2] +. fempty <.> "abc" +. [3,4,5] +. fempty--- [["abc","cba","bc"],[1,2,3,4,5]]-instance Semigroup a => Apply (FlipSeparated a) where- FlipSeparated x <.> FlipSeparated y =- FlipSeparated (separatedSwap # (x ^. separatedSwap <.> y ^. separatedSwap))---- | Applies functions with separator values, using a zipping operation, appending--- elements. The identity operation is an infinite list of the empty element--- and the given separator value.------ >>> (fempty :: FlipSeparated [Int] (String -> [String])) <*> fempty--- []------ >>> (\s -> [s, reverse s, drop 1 s]) +. [1,2] +. fempty <*> "abc" +. [3,4,5] +. fempty--- [["abc","cba","bc"],[1,2,3,4,5]]-instance Monoid s => Applicative (FlipSeparated s) where - FlipSeparated x <*> FlipSeparated y =- FlipSeparated (separatedSwap # (x ^. separatedSwap <*> y ^. separatedSwap))- pure =- FlipSeparated . (#) separatedSwap . pure--instance (Show s, Show a) => Show (FlipSeparated s a) where- show (FlipSeparated x) =- show x--instance Semigroup (FlipSeparated s a) where- FlipSeparated x <> FlipSeparated y =- FlipSeparated (x <> y) --instance Monoid (FlipSeparated s a) where- mappend =- (<>)- mempty =- FlipSeparated mempty--instance FlipSeparatedCons FlipSeparated1 FlipSeparated where- type FlipSeparatedConsF FlipSeparated = FlipSeparated1- type FlipSeparatedConsG FlipSeparated1 = FlipSeparated- s +. p =- (s +: flipSeparated1 # p) ^. flipSeparated---- | The isomorphism to a @Separator@.------ >>> empty ^. flipSeparated--- []------ >>> ('x' +: 6 +: empty) ^. flipSeparated--- ['x',6]------ >>> [] ^. separated . flipSeparated--- []------ >>> [(6, [])] ^. separated . flipSeparated--- [6,[]]-flipSeparated ::- Iso (Separated s a) (Separated t b) (FlipSeparated a s) (FlipSeparated b t) -flipSeparated =- iso FlipSeparated (\(FlipSeparated x) -> x) --fempty ::- FlipSeparated a s-fempty =- FlipSeparated empty--newtype FlipSeparated1 s a =- FlipSeparated1 (Separated1 a s)--instance Bifunctor FlipSeparated1 where- bimap f g (FlipSeparated1 x) =- FlipSeparated1 (bimap g f x)--instance Functor (FlipSeparated1 a) where- fmap =- bimap id---- | Applies functions with element values, using a zipping operation,--- appending separators.------ >>> fmap toUpper +. [3,4] +. reverse +. fempty <.> "abc" +. [5,6,7] +. "def" +. fempty--- ["ABC",[3,4,5,6,7],"fed"]-instance Semigroup a => Apply (FlipSeparated1 a) where- (<.>) =- flipSeparated1Ap (<>)---- | Applies functions with element values, using a zipping operation,--- appending separators. The identity operation is an infinite list of the empty--- separator and the given element value.------ >>> fmap toUpper +. [3,4] +. reverse +. fempty <*> "abc" +. [5,6,7] +. "def" +. fempty--- ["ABC",[3,4,5,6,7],"fed"]-instance Monoid s => Applicative (FlipSeparated1 s) where - (<*>) =- flipSeparated1Ap mappend- pure a =- FlipSeparated1 ((a, pure a) ^. separated1)--instance (Show s, Show a) => Show (FlipSeparated1 s a) where- show (FlipSeparated1 x) =- show x---- | The isomorphism to a @Separated1@.------ >>> single 6 ^. flipSeparated1--- [6]------ >>> (5 +: 'x' +: single 6) ^. flipSeparated1--- [5,'x',6]------ >>> (6 +: empty) ^. flipSeparated1--- [6]------ >>> (5 +: 'x' +: 6 +: empty) ^. flipSeparated1--- [5,'x',6]-flipSeparated1 ::- Iso (Separated1 a s) (Separated1 b t) (FlipSeparated1 s a) (FlipSeparated1 t b)-flipSeparated1 =- iso FlipSeparated1 (\(FlipSeparated1 x) -> x)--instance FlipSeparatedCons FlipSeparated FlipSeparated1 where- type FlipSeparatedConsF FlipSeparated1 = FlipSeparated- type FlipSeparatedConsG FlipSeparated = FlipSeparated1- a +. p =- (a +: flipSeparated # p) ^. flipSeparated1--------flipSeparated1Ap ::- (s -> s -> s)- -> FlipSeparated1 s (a -> b)- -> FlipSeparated1 s a- -> FlipSeparated1 s b-flipSeparated1Ap op (FlipSeparated1 x) (FlipSeparated1 y) =- let (f, fs) = separated1 # x- (a, as) = separated1 # y- in FlipSeparated1 ((f a, zipWith (\(s, f') (t, a') -> (s `op` t, f' a')) (separated # fs) (separated # as) ^. separated) ^. separated1)
− src/Data/Separated/FlipSeparatedCons.hs
@@ -1,18 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE MultiParamTypeClasses #-}--module Data.Separated.FlipSeparatedCons(- FlipSeparatedCons(..)-) where---- | Prepend a value to a separated-like structure.-class (f ~ FlipSeparatedConsF g, g ~ FlipSeparatedConsG f) => FlipSeparatedCons f g where- type FlipSeparatedConsF g :: * -> * -> *- type FlipSeparatedConsG f :: * -> * -> *- (+.) ::- s- -> f s a- -> g a s--infixr 5 +.
src/Data/Separated/Separated.hs view
@@ -17,54 +17,53 @@ , (.++.) , (++.) , (.++)+, separatedBy+, separatedBy1 ) where -import Control.Applicative(Applicative((<*>), pure))-import Control.Category(Category(id, (.)))-import Control.Lens.Iso(Iso, iso, from)-import Control.Lens.Tuple(_1, _2)-import Control.Lens.Type(Lens)-import Data.Functor(Functor(fmap))-import Data.Functor.Apply(Apply((<.>)))-import Data.Bifunctor(Bifunctor(bimap))-import Data.Eq(Eq)+import Control.Applicative(Alternative(many))+import Data.Bifoldable+import Data.Bitraversable+import Data.Functor.Apply as Apply((<.>)) import Data.List(intercalate, zipWith, repeat)-import Data.Monoid(Monoid(mappend, mempty))-import Data.Ord(Ord)-import Data.Semigroup(Semigroup((<>)))+import Data.Monoid as Monoid(mappend)+import Data.Semigroup as Semigroup((<>)) import Data.Separated.SeparatedCons(SeparatedCons((+:), SeparatedConsF, SeparatedConsG)) import Data.String(String)-import Data.Tuple(uncurry)-import Prelude(Show(show))-import Control.Lens((^.), (#))+import Papa hiding ((<.>)) -- $setup -- >>> :set -XNoImplicitPrelude--- >>> import Control.Lens.Review((#))--- >>> import Control.Monad(Monad(return)) -- >>> import Data.Char(toUpper)--- >>> import Data.Eq(Eq((==)))--- >>> import Data.List(reverse, drop)--- >>> import Control.Lens(set, (^.))--- >>> import Prelude(Num(..), String, Int)+-- >>> import Data.Either(isLeft)+-- >>> import Text.Parsec(parse, char, digit) -- >>> import Test.QuickCheck(Arbitrary(..)) -- >>> instance (Arbitrary s, Arbitrary a) => Arbitrary (Separated s a) where arbitrary = fmap (^. separated) arbitrary -- >>> instance (Arbitrary a, Arbitrary s) => Arbitrary (Separated1 s a) where arbitrary = do a <- arbitrary; x <- arbitrary; return ((a, x) ^. separated1) -data Separated s a =- Separated [(s, a)]++newtype Separated a b =+ Separated [(a, b)] deriving (Eq, Ord) instance Bifunctor Separated where bimap f g (Separated x) = Separated (fmap (bimap f g) x) +instance Bifoldable Separated where+ bifoldr f g z (Separated x) =+ foldr (\(a, b) -> f a . g b) z x++instance Bitraversable Separated where+ bitraverse f g (Separated x) =+ Separated <$> traverse (\(a, b) -> (,) <$> f a <*> g b) x+ -- | Map across a @Separated@ on the element values. -- -- prop> fmap id (x :: Separated Int String) == x ----- prop> fmap (+1) (a +: b +: empty) == a +: (1+b) +: empty-instance Functor (Separated s) where+-- prop> \a b -> fmap (+1) (a +: b +: empty) == a +: (1+b) +: empty+instance Functor (Separated a) where fmap = bimap id @@ -76,7 +75,7 @@ -- -- >>> [1,2] +: (\s -> [s, reverse s, drop 1 s]) +: empty <.> [3,4,5] +: "abc" +: empty -- [[1,2,3,4,5],["abc","cba","bc"]]-instance Semigroup s => Apply (Separated s) where+instance Semigroup a => Apply (Separated a) where (<.>) = separatedAp (<>) @@ -89,21 +88,21 @@ -- -- >>> [1,2] +: (\s -> [s, reverse s, drop 1 s]) +: empty <*> [3,4,5] +: "abc" +: empty -- [[1,2,3,4,5],["abc","cba","bc"]]-instance Monoid s => Applicative (Separated s) where +instance (Semigroup a, Monoid a) => Applicative (Separated a) where (<*>) =- separatedAp mappend+ separatedAp (<>) pure = Separated . repeat . (,) mempty -instance (Show s, Show a) => Show (Separated s a) where+instance (Show a, Show b) => Show (Separated a b) where show (Separated x) = showSeparated id x -instance Semigroup (Separated s a) where+instance Semigroup (Separated a b) where Separated x <> Separated y = Separated (x <> y) -instance Monoid (Separated s a) where+instance Monoid (Separated a b) where mappend = (<>) mempty =@@ -115,28 +114,10 @@ s +: Separated1 a (Separated x) = Separated ((s, a) : x) --- | The isomorphism to a list of pairs of element and separator values.------ >>> separated # empty--- []------ >>> separated # ('x' +: 6 +: empty)--- [('x',6)]------ >>> [] ^. separated--- []------ >>> [(6, [])] ^. separated--- [6,[]]-separated ::- Iso [(s, a)] [(t, b)] (Separated s a) (Separated t b)-separated =- iso Separated (\(Separated x) -> x)- ---- -data Separated1 a s =- Separated1 a (Separated s a)+data Separated1 b a =+ Separated1 b (Separated a b) deriving (Eq, Ord) instance Bifunctor Separated1 where@@ -151,7 +132,7 @@ -- prop> fmap id (x :: Separated1 Int String) == x -- -- prop> fmap (+1) (single x) == single x-instance Functor (Separated1 s) where+instance Functor (Separated1 b) where fmap = bimap id @@ -160,11 +141,11 @@ -- -- >>> [1,2] +: reverse +: [3,4] +: empty <.> [5,6,7] +: "abc" +: [8] +: empty -- [[1,2,5,6,7],"cba",[3,4,8]]-instance Semigroup s => Apply (Separated1 s) where+instance Semigroup b => Apply (Separated1 b) where (<.>) = separated1Ap (<>) -instance (Show a, Show s) => Show (Separated1 a s) where+instance (Show b, Show a) => Show (Separated1 b a) where show (Separated1 a (Separated x)) = showSeparated (show a:) x @@ -174,12 +155,43 @@ -- -- >>> [1,2] +: reverse +: [3,4] +: empty <*> [5,6,7] +: "abc" +: [8] +: empty -- [[1,2,5,6,7],"cba",[3,4,8]]-instance Monoid s => Applicative (Separated1 s) where +instance (Semigroup b, Monoid b) => Applicative (Separated1 b) where (<*>) =- separated1Ap mappend+ separated1Ap (<>) pure =- Separated1 mempty . swapSeparated . pure+ Separated1 mempty . (separatedSwap #) . pure +instance SeparatedCons Separated Separated1 where+ type SeparatedConsF Separated1 = Separated+ type SeparatedConsG Separated = Separated1+ (+:) =+ Separated1++----++-- | The isomorphism to a list of pairs of element and separator values.+--+-- >>> separated # empty+-- []+--+-- >>> separated # ('x' +: 6 +: empty)+-- [('x',6)]+--+-- >>> [] ^. separated+-- []+--+-- >>> [(6, [])] ^. separated+-- [6,[]]+separated ::+ Iso [(a, b)] [(c, d)] (Separated a b) (Separated c d)+separated =+ iso Separated (\(Separated x) -> x)++empty ::+ Separated s a+empty =+ Separated []+ -- | The isomorphism to element values interspersed with a separator. -- -- >>> separated1 # (single 6)@@ -198,12 +210,6 @@ separated1 = iso (uncurry Separated1) (\(Separated1 a x) -> (a, x)) -instance SeparatedCons Separated Separated1 where- type SeparatedConsF Separated1 = Separated- type SeparatedConsG Separated = Separated1- (+:) =- Separated1- -- | A lens on the first element value. -- -- >>> single 7 ^. separated1Head@@ -223,13 +229,6 @@ separated1Tail = from separated1 . _2 -------empty ::- Separated s a-empty =- Separated []- -- | One element and one separator. -- -- >>> 7 +- "abc"@@ -244,6 +243,8 @@ s +- a = s +: single a +infixl 9 +-+ -- | Zero element values interspersed with one element. -- -- >>> single 4@@ -303,7 +304,6 @@ let swap (a, b) = (b, a) in iso (\(Separated x) -> Separated (fmap swap x)) (\(Separated x) -> Separated (fmap swap x)) - -- | Append two lists of separated values to produce a list of pairs of separator and element values. -- -- >>> single 7 .++. single 'a'@@ -312,7 +312,7 @@ -- 'a' +: single 7 .++. single 'b' -- ['a',7,'b'] ----- prop> a +: (b .++. c) == (a +: b) *+: c+-- prop> a +: (b :: Separated Int Int) == a +: b -- (a +: (b .++. c)) == ((a +: b) .++ c) (.++.) :: Separated1 s a -> Separated1 a s@@ -362,9 +362,55 @@ infixr 5 .++ ---- -- values, separators, lookup, FlipSeparated, combinators+-- |+--+-- >>> parse (separatedBy (char ',') digit) "test" ""+-- Right []+--+-- >>> isLeft (parse (separatedBy (char ',') digit) "test" ",")+-- True+--+-- >>> parse (separatedBy (char ',') digit) "test" ",1"+-- Right [',','1']+--+-- >>> isLeft (parse (separatedBy (char ',') digit) "test" ",1,")+-- True+--+-- >>> parse (separatedBy (char ',') digit) "test" ",1,2,3,4,5"+-- Right [',','1',',','2',',','3',',','4',',','5']+separatedBy ::+ Alternative f =>+ f a+ -> f b+ -> f (Separated a b)+separatedBy a b =+ Separated <$>+ many+ ((,) <$> a <*> b) -----+-- |+--+-- >>> isLeft (parse (separatedBy1 (char ',') digit) "test" "")+-- True+--+-- >>> parse (separatedBy1 (char ',') digit) "test" ","+-- Right [',']+--+-- >>> isLeft (parse (separatedBy1 (char ',') digit) "test" ",1")+-- True+--+-- >>> parse (separatedBy1 (char ',') digit) "test" ",1,"+-- Right [',','1',',']+--+-- >>> parse (separatedBy1 (char ',') digit) "test" ",1,2,3,4,5,"+-- Right [',','1',',','2',',','3',',','4',',','5',',']+separatedBy1 ::+ Alternative f =>+ f b+ -> f a+ -> f (Separated1 b a)+separatedBy1 b a =+ Separated1 <$> b <*> separatedBy a b showSeparated :: (Show a, Show s, Functor f) =>@@ -379,19 +425,13 @@ -> Separated s (a -> b) -> Separated s a -> Separated s b-separatedAp op (Separated f) (Separated a) =- Separated (zipWith (\(s, f') (t, a') -> (s `op` t, f' a')) f a) +separatedAp opp (Separated f) (Separated a) =+ Separated (zipWith (\(s, f') (t, a') -> (s `opp` t, f' a')) f a) separated1Ap :: (a -> a -> a) -> Separated1 a (s -> t) -> Separated1 a s -> Separated1 a t-separated1Ap op (Separated1 f (Separated fs)) (Separated1 a (Separated as)) =- Separated1 (f `op` a) (Separated (zipWith (\(s, f') (t, a') -> (s t, f' `op` a')) fs as))--swapSeparated ::- Separated s a- -> Separated a s-swapSeparated (Separated x) =- Separated (fmap (\(s, a) -> (a, s)) x)+separated1Ap opp (Separated1 f (Separated fs)) (Separated1 a (Separated as)) =+ Separated1 (f `opp` a) (Separated (zipWith (\(s, f') (t, a') -> (s t, f' `opp` a')) fs as))
src/Data/Separated/SeparatedCons.hs view
@@ -12,7 +12,7 @@ type SeparatedConsG f :: * -> * -> * (+:) :: a- -> f s a- -> g a s-+ -> f b a+ -> g a b+ infixr 5 +: