separated 0.0.3 → 0.0.4
raw patch · 2 files changed
+94/−4 lines, 2 filesdep +semigroupoids
Dependencies added: semigroupoids
Files
- separated.cabal +3/−2
- src/Data/Separated.hs +91/−2
separated.cabal view
@@ -1,5 +1,5 @@ name: separated-version: 0.0.3+version: 0.0.4 license: BSD3 license-File: etc/LICENCE author: Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>@@ -9,7 +9,7 @@ category: Data description: A data type with elements separated by values homepage: https://github.com/tonymorris/separated-bug-reports: https://github.com/tonymorris/route/separated+bug-reports: https://github.com/tonymorris/separated/separated cabal-version: >= 1.10 build-type: Custom @@ -28,6 +28,7 @@ base < 5 && >= 3 , lens >= 3.10 , semigroups >= 0.9+ , semigroupoids >= 4.0 ghc-options: -Wall
src/Data/Separated.hs view
@@ -24,6 +24,7 @@ , separators1 -- * Lenses and isomorphisms , separatedIso+, separatedSwap , separated1Iso , shift , separated1Head@@ -33,17 +34,20 @@ , separatedWith1 ) where -import Prelude(Eq, Ord, Show(..), Functor(..), Monad(..), fst, snd, (.))+import Prelude(Eq, Ord, Show(..), Functor(..), Monad(..), fst, snd, id, (.)) import Data.List.NonEmpty(NonEmpty(..))-import Data.List(intercalate)+import Data.List(intercalate, zipWith, repeat) import Control.Lens(Lens', Iso', lens, iso, (#), (^.)) import Data.Semigroup(Semigroup(..))+import Data.Monoid(Monoid(..)) import Data.Functor((<$>)) import Data.Maybe(Maybe(..)) import Control.Applicative(Applicative(..), Alternative(many, (<|>)))+import Data.Functor.Apply(Apply(..)) -- $setup -- >>> import Prelude(Eq(..), Num(..), String, Int, id)+-- >>> import Data.List(reverse, drop) -- >>> import Control.Lens(set, (^.)) -- >>> import Test.QuickCheck(Arbitrary(..)) -- >>> instance (Arbitrary s, Arbitrary a) => Arbitrary (Separated s a) where arbitrary = fmap Separated arbitrary@@ -70,6 +74,42 @@ fmap f (Separated x) = Separated (fmap (\(a, b) -> (a, f b)) x) +-- not exported+separatedAp ::+ (s -> s -> s)+ -> 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)++-- | Applies functions with element values, using a zipping operation, appending+-- separators.+--+-- >>> (empty :: Separated [Int] (String -> [String])) <.> empty+-- []+--+-- >>> [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+ (<.>) =+ separatedAp (<>)++-- | 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.+--+-- >>> (empty :: Separated [Int] (String -> [String])) <*> empty+-- []+--+-- >>> [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+ (<*>) =+ separatedAp mappend+ pure a =+ Separated (repeat (mempty, a))+ -- | A data type representing element values interspersed with a separator. -- -- There is one fewer separator values (@s@) than there are element values (@a@). There is at least one element value.@@ -96,6 +136,36 @@ fmap f (Separated1 a x) = Separated1 a (fmap (\(s, y) -> (f s, y)) x) +-- not exported+separated1Ap ::+ (a -> a -> a)+ -> Separated1 a (s -> t)+ -> Separated1 a s+ -> Separated1 a t+separated1Ap op (Separated1 a f) (Separated1 b s) =+ Separated1 (a `op` b) (zipWith (\(f', s') (x, t') -> (f' x, s' `op` t')) f s)++-- | Applies functions with separator values, using a zipping operation,+-- appending elements.+--+-- >>> [1,2] +: reverse +: [3,4] +: empty <.> [5,6,7] +: "abc" +: [8] +: empty+-- [[1,2,5,6,7],"cba",[3,4,8]]+instance Semigroup a => Apply (Separated1 a) where+ (<.>) =+ separated1Ap (<>)++-- | Applies functions with element values, using a zipping operation, appending+-- elements. The identity operation is an infinite list of the empty element+-- and the given separator value.+--+-- >>> [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+ (<*>) =+ separated1Ap mappend+ pure a =+ Separated1 mempty (repeat (a, mempty))+ -- | Prepend a value to a separated-like structure. -- -- >>> 'z' +: empty@@ -303,6 +373,25 @@ Iso' [(s, a)] (Separated s a) separatedIso = iso Separated (\(Separated x) -> x)++-- | The isomorphism that swaps elements with their separators.+--+-- >>> separatedSwap # empty+-- []+--+-- >>> separatedSwap # ('x' +: 6 +: empty)+-- [6,'x']+--+-- >>> empty ^. separatedSwap+-- []+--+-- >>> ('x' +: 6 +: empty) ^. separatedSwap+-- [6,'x']+separatedSwap ::+ Iso' (Separated s a) (Separated a s)+separatedSwap =+ let swap (a, b) = (b, a)+ in iso (\(Separated x) -> Separated (fmap swap x)) (\(Separated x) -> Separated (fmap swap x)) -- | The isomorphism to element values interspersed with a separator. --