transaction 0.1.0.0 → 0.1.1.0
raw patch · 4 files changed
+695/−23 lines, 4 filesdep +QuickCheckdep +hspecdep +mono-traversable
Dependencies added: QuickCheck, hspec, mono-traversable
Files
- README.md +1/−0
- src/Data/Transaction.hs +274/−20
- test/Spec.hs +414/−1
- transaction.cabal +6/−2
README.md view
@@ -6,3 +6,4 @@ # Haskell-transaction Monadic representation of transactions.+Alike `List`, but can be declared with `do` notations.
src/Data/Transaction.hs view
@@ -1,4 +1,10 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeFamilies #-} {- | Module : Data.Transaction@@ -14,26 +20,67 @@ module Data.Transaction ( -- * Constructors- action-+ action -- * Converters , reduce , toList , tMap , tFilter , tFilterMap- -- * Types , Transaction , TransactionM ) where +import Prelude hiding+ ( all+ , any+ , drop+ , dropWhile+ , filter+ , foldMap+ , foldl+ , foldl1+ , foldr+ , foldr1+ , head+ , init+ , last+ , length+ , null+ , repeat+ , replicate+ , span+ , tail+ , take+ , takeWhile+ )++import Data.Bifunctor (Bifunctor(..))+import qualified Data.Monoid as Monoid+import Data.MonoTraversable+ ( Element+ , GrowingAppend+ , MonoFoldable(..)+ , MonoFunctor(..)+ , MonoPointed(..)+ , MonoTraversable(..)+ )+import Data.Semigroup as Sem+import Data.Sequences+ ( Index+ , IsSequence(..)+ , SemiSequence(..)+ , defaultSnoc+ , defaultSortBy+ )+ {- ============== - Types - ============== -}- data TransactionM a x- = TVal a (TransactionM a x)+ = TVal a+ (TransactionM a x) | TNull x deriving (Functor) @@ -49,10 +96,206 @@ TVal a next >>= f = TVal a (next >>= f) TNull a >>= f = f a +instance Sem.Semigroup (Transaction a) where+ TVal a next <> t = TVal a (next <> t)+ TNull _ <> t = t++instance Monoid (Transaction a) where+ mempty = TNull ()+#if !(MIN_VERSION_base(4,11,0))+ mappend = (<>)+#endif++instance Bifunctor TransactionM where+ first :: forall a b x. (a -> b) -> TransactionM a x -> TransactionM b x+ first _ (TNull a) = pure a+ first f (TVal a next) = TVal (f a) $ first f next+ second :: forall a x y. (x -> y) -> TransactionM a x -> TransactionM a y+ second = fmap++type instance Element (Transaction a) = a++instance MonoFunctor (Transaction a) where+ omap :: (a -> a) -> Transaction a -> Transaction a+ omap = first++instance MonoFoldable (Transaction a) where+ otoList = toList+ ocompareLength :: Integral i => Transaction a -> i -> Ordering+ ocompareLength (TNull ()) i = 0 `compare` i+ ocompareLength (TVal _ next) i+ | i <= 0 = GT+ | otherwise = ocompareLength next (i - 1)+ ofoldMap = foldMap+ ofoldr = foldr+ ofoldl' = foldl'+ ofoldr1Ex = foldr1+ ofoldl1Ex' = foldl1'++foldMap :: (Monoid m) => (a -> m) -> Transaction a -> m+foldMap f = foldr (\x m -> f x Monoid.<> m) mempty++foldr :: (a -> b -> b) -> b -> Transaction a -> b+foldr _ b (TNull ()) = b+foldr f b (TVal a next) = f a (foldr f b next)++foldl :: (b -> a -> b) -> b -> Transaction a -> b+foldl f b (TVal a next) = foldl f (f b a) next+foldl _ b (TNull ()) = b++foldl' :: (b -> a -> b) -> b -> Transaction a -> b+foldl' (??) z xs = (foldr (?!) id xs) z+ where+ x ?! g = g . (?? x)++foldr1 :: (a -> a -> a) -> Transaction a -> a+foldr1 _ (TNull ()) = error "Transaction.foldr1: empty transaction"+foldr1 _ (TVal a (TNull ())) = a+foldr1 f (TVal a next) = f a (foldr1 f next)++foldl1' :: (a -> a -> a) -> Transaction a -> a+foldl1' _ (TNull ()) = error "Transaction.foldl1': empty transaction"+foldl1' f (TVal a next) = foldl' f a next++#if MIN_VERSION_base(4,11,0)+{-# NOINLINE [1] length #-}+length :: Transaction a -> Int+length t = lenAcc t 0++lenAcc :: Transaction a -> Int -> Int+lenAcc (TNull ()) n = n+lenAcc (TVal _ next) n = lenAcc next (n + 1)+#endif++instance MonoPointed (Transaction a) where+ opoint :: a -> Transaction a+ opoint = action++instance SemiSequence (Transaction a) where+ type Index (Transaction a) = Int+ intersperse :: a -> Transaction a -> Transaction a+ intersperse _ (TNull ()) = pure ()+ intersperse sep (TVal a next) = TVal a $ prependToAll sep next+ reverse :: Transaction a -> Transaction a+ reverse = reduce (\t a -> TVal a t) (TNull ())+ find :: (a -> Bool) -> Transaction a -> Maybe a+ find p t =+ case tFilter p t of+ TNull () -> Nothing+ TVal a _ -> Just a+ sortBy :: (a -> a -> Ordering) -> Transaction a -> Transaction a+ sortBy = defaultSortBy+ cons :: a -> Transaction a -> Transaction a+ cons a t = TVal a t+ snoc :: Transaction a -> a -> Transaction a+ snoc = defaultSnoc++prependToAll :: a -> Transaction a -> Transaction a+prependToAll _ (TNull ()) = pure ()+prependToAll sep (TVal a next) = TVal sep $ TVal a $ prependToAll sep next++instance GrowingAppend (Transaction a)++instance MonoTraversable (Transaction a) where+ otraverse :: Applicative f => (a -> f a) -> Transaction a -> f (Transaction a)+ otraverse _ (TNull ()) = pure $ pure ()+ otraverse f (TVal a next) = TVal <$> f a <*> otraverse f next++instance IsSequence (Transaction a) where+ fromList :: [a] -> Transaction a+ fromList [] = pure ()+ fromList (x:xs) = TVal x $ fromList xs++#if MIN_VERSION_mono_traversable(1,0,2)+ lengthIndex :: Transaction a -> Int+ lengthIndex = length+#endif++ {-# NOINLINE [1] filter #-}+ filter :: (a -> Bool) -> Transaction a -> Transaction a+ filter _ (TNull ()) = pure ()+ filter p (TVal a next)+ | p a = TVal a $ filter p next+ | otherwise = filter p next+ filterM :: Monad m => (a -> m Bool) -> Transaction a -> m (Transaction a)+ filterM _ (TNull ()) = pure $ pure ()+ filterM mp (TVal a next) = do+ b <- mp a+ next' <- filterM mp next+ pure $+ if b+ then TVal a next'+ else next'+ break :: (a -> Bool) -> Transaction a -> (Transaction a, Transaction a)+ break p = span (not . p)+ span :: (a -> Bool) -> Transaction a -> (Transaction a, Transaction a)+ span _ t@(TNull ()) = (t, t)+ span p t@(TVal a next)+ | p a =+ let (y, z) = span p next+ in (TVal a y, z)+ | otherwise = (pure (), t)+ dropWhile :: (a -> Bool) -> Transaction a -> Transaction a+ dropWhile _ (TNull ()) = pure ()+ dropWhile p t@(TVal a next)+ | p a = dropWhile p next+ | otherwise = t+ takeWhile :: (a -> Bool) -> Transaction a -> Transaction a+ takeWhile _ (TNull ()) = pure ()+ takeWhile p (TVal a next)+ | p a = TVal a $ takeWhile p next+ | otherwise = pure ()+ splitAt :: Int -> Transaction a -> (Transaction a, Transaction a)+ splitAt n t = (take n t, drop n t)+ take :: Int -> Transaction a -> Transaction a+ take n _+ | n <= 0 = pure ()+ take _ (TNull ()) = pure ()+ take n (TVal a next) = TVal a $ take (n - 1) next+ drop :: Int -> Transaction a -> Transaction a+ drop n t+ | n <= 0 = t+ drop _ (TNull ()) = pure ()+ drop n (TVal _ next) = drop (n - 1) next+ uncons :: Transaction a -> Maybe (a, Transaction a)+ uncons (TNull ()) = Nothing+ uncons (TVal a next) = Just (a, next)+ unsnoc (TNull ()) = Nothing+ unsnoc (TVal a0 next0) = Just (loop id a0 next0)+ where+ loop front a (TNull ()) = (front $ pure (), a)+ loop front a (TVal y z) = loop (front . (TVal a)) y z+ {-# INLINE partition #-}+ partition :: (a -> Bool) -> Transaction a -> (Transaction a, Transaction a)+ partition p t = foldr (select p) (pure (), pure ()) t+ {-# INLINE replicate #-}+ replicate :: Int -> a -> Transaction a+ replicate n a = take n (repeat a)+ replicateM :: Monad m => Int -> m a -> m (Transaction a)+ replicateM cnt0 f = loop cnt0+ where+ loop cnt+ | cnt <= 0 = pure $ pure ()+ | otherwise = TVal <$> f <*> loop (cnt - 1)++{-# INLINE [0] repeat #-}+repeat :: a -> Transaction a+repeat a = t+ where+ t = TVal a t++select ::+ (a -> Bool)+ -> a+ -> (Transaction a, Transaction a)+ -> (Transaction a, Transaction a)+select p x ~(ts, fs)+ | p x = (TVal x ts, fs)+ | otherwise = (ts, TVal x fs)+ {- ============== - Operators - ============== -}- {- | >>> :{ toList $ do@@ -61,6 +304,14 @@ action 6 :} [4,5,6]++>>> :{+toList $ filter even $ do+ action 4+ action 5+ action 6+:}+[4,6] -} action :: a -> Transaction a action a = TVal a $ pure ()@@ -68,8 +319,7 @@ {- ============== - Converters - ============== -}--{- |+{- | An alias of 'first' for convenience. >>> :{ toList $ do action 4@@ -83,7 +333,11 @@ tMap :: (a -> b) -> Transaction a -> Transaction b tMap f = tFilterMap (pure . f) -{- |+{-# DEPRECATED+tFilter "Use `IsSequence.filter` instead."+ #-}++{- | An alias of 'filter'. >>> :{ toList $ do action 4@@ -95,11 +349,12 @@ [4,6,7] -} tFilter :: (a -> Bool) -> Transaction a -> Transaction a-tFilter p = tFilterMap $ \a ->- if p a- then Just a- else Nothing+tFilter = filter +{-# DEPRECATED+tFilterMap "This will be removed in a future release."+ #-}+ {- | >>> :{ toList $ do@@ -114,15 +369,14 @@ tFilterMap :: (a -> Maybe b) -> Transaction a -> Transaction b tFilterMap f (TVal a next) = case f a of- Just b ->- TVal b $ tFilterMap f next- Nothing ->- tFilterMap f next+ Just b -> TVal b $ tFilterMap f next+ Nothing -> tFilterMap f next tFilterMap _ (TNull ()) = TNull () +{- | An alias of `foldl` for convenience.+-} reduce :: (b -> a -> b) -> b -> Transaction a -> b-reduce f b (TVal a next) = reduce f (f b a) next-reduce _ b (TNull ()) = b+reduce = foldl toList :: Transaction a -> [a]-toList trans = reduce (\f a -> f . (a:)) id trans []+toList trans = reduce (\f a -> f . (a :)) id trans []
test/Spec.hs view
@@ -1,2 +1,415 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Main where++import Prelude hiding+ ( all+ , any+ , break+ , drop+ , dropWhile+ , filter+ , foldMap+ , foldl+ , foldl1+ , foldr+ , foldr1+ , head+ , init+ , last+ , length+ , repeat+ , null+ , replicate+ , reverse+ , seq+ , span+ , splitAt+ , tail+ , take+ , takeWhile+ )+import Data.Bifunctor (Bifunctor(..))+import Data.MonoTraversable+ ( MonoFoldable(..)+ , MonoFunctor(..)+ , MonoPointed(..)+ , MonoTraversable(..)+ )+import Data.Sequences (IsSequence(..), SemiSequence(..))+import Data.Transaction+import Test.Hspec+import Test.Hspec.QuickCheck+import Test.QuickCheck+import Test.QuickCheck.Exception+ main :: IO ()-main = putStrLn "Test suite not yet implemented"+main = hspec spec++exceptionableEq :: Eq a => Either AnException a -> Either AnException a -> Bool+exceptionableEq (Left _) (Left _) = True+exceptionableEq (Right a) (Right b) = a == b+exceptionableEq _ _ = False++spec :: Spec+spec = do+ describe "MonoFunctor" $ do+ describe "omap" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (a :: [Int]) ->+ omap f a == (toList . omap f . listToTrans) a++ describe "MonoFoldable" $ do+ describe "ofoldMap" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (a :: [Int]) ->+ (ofoldMap f a :: String) ==+ (ofoldMap f $ listToTrans a)+ describe "ofoldr" $ do+ prop "is equivalent to list" $+ \f (a :: String) (mono :: [Int]) ->+ (ofoldr (applyFun2 f) a mono) ==+ (ofoldr (applyFun2 f) a $ listToTrans mono)+ describe "ofoldl'" $ do+ prop "is equivalent to list" $+ \f (a :: String) (mono :: [Int]) ->+ (ofoldl' (applyFun2 f) a mono) ==+ (ofoldl' (applyFun2 f) a $ listToTrans mono)+ describe "otoList" $ do+ prop "is equivalent to list" $+ \(mono :: [Int]) ->+ otoList (listToTrans mono) == mono+ describe "oall" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (mono :: [Int]) ->+ (oall f mono) ==+ (oall f $ listToTrans mono)+ describe "oany" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (mono :: [Int]) ->+ (oany f mono) ==+ (oany f $ listToTrans mono)+ describe "onull" $ do+ prop "is equivalent to list" $+ \(mono :: [Int]) ->+ (onull mono) ==+ (onull $ listToTrans mono)+ describe "olength" $ do+ prop "is equivalent to list" $+ \(mono :: [Int]) ->+ (olength mono) ==+ (olength $ listToTrans mono)+ describe "olength64" $ do+ prop "is equivalent to list" $+ \(mono :: [Int]) ->+ (olength64 mono) ==+ (olength64 $ listToTrans mono)+ describe "ocompareLength" $ do+ prop "is equivalent to list" $+ \(i :: Integer) (mono :: [String]) ->+ (ocompareLength mono i) ==+ (ocompareLength (listToTrans mono) i)+ describe "otraverse_" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (mono :: [Int]) ->+ (otraverse_ (f :: Int -> Maybe String) mono) ==+ (otraverse_ f $ listToTrans mono)+ describe "ofor_" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (mono :: [Int]) ->+ (ofor_ mono (f :: Int -> Maybe String)) ==+ (ofor_ (listToTrans mono) f)+ describe "omapM_" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (mono :: [Int]) ->+ (omapM_ (f :: Int -> Maybe ()) mono) ==+ (omapM_ f (listToTrans mono))+ describe "oforM_" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (mono :: [Int]) ->+ (ofor_ mono (f :: Int -> Maybe ())) ==+ (ofor_ (listToTrans mono) f)+ describe "ofoldlM" $ do+ prop "is equivalent to list" $+ \f (a :: String) (mono :: [Int]) ->+ (ofoldlM (applyFun2 f) a mono :: Maybe String) ==+ (ofoldlM (applyFun2 f) a (listToTrans mono))+ describe "ofoldMap1Ex" $ do+ it "is equivalent to list" $ again $ \(Fun _ f) (mono :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (ofoldMap1Ex f mono :: String)+ <*> tryEvaluate (ofoldMap1Ex f (listToTrans mono))+ describe "ofoldr1Ex" $ do+ it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (ofoldr1Ex (applyFun2 f) mono)+ <*> tryEvaluate (ofoldr1Ex (applyFun2 f) (listToTrans mono))+ describe "ofoldl1Ex'" $ do+ it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (ofoldl1Ex' (applyFun2 f) mono)+ <*> tryEvaluate (ofoldl1Ex' (applyFun2 f) (listToTrans mono))+ describe "headEx" $ do+ it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (headEx mono)+ <*> tryEvaluate (headEx (listToTrans mono))+ describe "lastEx" $ do+ it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (lastEx mono)+ <*> tryEvaluate (lastEx (listToTrans mono))+ describe "unsafeHead" $ do+ it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (unsafeHead mono)+ <*> tryEvaluate (unsafeHead (listToTrans mono))+ describe "unsafeLast" $ do+ it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (unsafeLast mono)+ <*> tryEvaluate (unsafeLast (listToTrans mono))+ describe "maximumByEx" $ do+ it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (maximumByEx (applyFun2 f) mono)+ <*> tryEvaluate (maximumByEx (applyFun2 f) (listToTrans mono))+ describe "minimumByEx" $ do+ it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (minimumByEx (applyFun2 f) mono)+ <*> tryEvaluate (minimumByEx (applyFun2 f) (listToTrans mono))++#if MIN_VERSION_mono_traversable(1,0,5)+ describe "oelem" $ do+ prop "is equivalent to list" $+ \(a :: Int) (mono :: [Int]) ->+ (oelem a mono) ==+ (oelem a (listToTrans mono))+ describe "onotElem" $ do+ prop "is equivalent to list" $+ \(a :: Int) (mono :: [Int]) ->+ (onotElem a mono) ==+ (onotElem a (listToTrans mono))+#endif++ describe "MonoPointed" $ do+ describe "opoint" $ do+ prop "is equivalent to list" $+ \(a :: Int) ->+ (opoint a) ==+ (toList $ opoint a)++ describe "SemiSequence" $ do+ describe "intersperse" $ do+ prop "is equivalent to list" $+ \(seq :: [Int]) a ->+ (intersperse a seq) ==+ (toList $ intersperse a $ listToTrans seq)+ describe "reverse" $ do+ prop "is equivalent to list" $+ \(seq :: [Int]) ->+ (reverse seq) ==+ (toList $ reverse $ listToTrans seq)+ describe "sortBy" $ do+ prop "is equivalent to list" $+ \f (seq :: [Int]) ->+ (sortBy (applyFun2 f) seq) ==+ (toList $ sortBy (applyFun2 f) $ listToTrans seq)+ describe "cons" $ do+ prop "is equivalent to list" $+ \a (seq :: [Int]) ->+ (cons a seq) ==+ (toList $ cons a $ listToTrans seq)+ describe "snoc" $ do+ prop "is equivalent to list" $+ \a (seq :: [Int]) ->+ (snoc seq a) ==+ (toList $ snoc (listToTrans seq) a)++ describe "MonoTraversable" $ do+ describe "otraverse" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (mono :: [Int]) ->+ (otraverse (f :: Int -> Maybe Int) mono) ==+ (toList <$> otraverse f (listToTrans mono))+ describe "omapM" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (mono :: [Int]) ->+ (otraverse (f :: Int -> Maybe Int) mono) ==+ (toList <$> otraverse f (listToTrans mono))++ describe "IsSequence" $ do+ describe "fromList" $ do+ prop "is equivalent to list" $+ \(seq :: [Int]) ->+ (toList $ fromList seq) == seq+#if MIN_VERSION_mono_traversable(1,0,2)+ describe "lengthIndex" $ do+ prop "is equivalent to list" $+ \(seq :: [Int]) ->+ (lengthIndex seq) ==+ (lengthIndex (listToTrans seq))+#endif+ describe "break" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (seq :: [Int]) ->+ (break f seq) ==+ (let (a,b) = break f (listToTrans seq) in (toList a, toList b))+ describe "span" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (seq :: [Int]) ->+ (span f seq) ==+ (let (a,b) = span f (listToTrans seq) in (toList a, toList b))+ describe "dropWhile" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (seq :: [Int]) ->+ (dropWhile f seq) ==+ (toList $ dropWhile f $ listToTrans seq)+ describe "takeWhile" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (seq :: [Int]) ->+ (takeWhile f seq) ==+ (toList $ takeWhile f $ listToTrans seq)+ describe "splitAt" $ do+ prop "is equivalent to list" $+ \n (seq :: [Int]) ->+ (splitAt n seq) ==+ (let (a,b) = splitAt n (listToTrans seq) in (toList a, toList b))+ describe "unsafeSplitAt" $ do+ prop "is equivalent to list" $+ \n (seq :: [Int]) ->+ (unsafeSplitAt n seq) ==+ (let (a,b) = unsafeSplitAt n (listToTrans seq) in (toList a, toList b))+ describe "take" $ do+ prop "is equivalent to list" $+ \n (seq :: [Int]) ->+ (take n seq) ==+ (toList $ take n $ fromList seq)+ describe "unsafeTake" $ do+ prop "is equivalent to list" $+ \n (seq :: [Int]) ->+ (unsafeTake n seq) ==+ (toList $ unsafeTake n $ fromList seq)+ describe "drop" $ do+ prop "is equivalent to list" $+ \n (seq :: [Int]) ->+ (drop n seq) ==+ (toList $ drop n $ fromList seq)+ describe "unsafeDrop" $ do+ prop "is equivalent to list" $+ \n (seq :: [Int]) ->+ (unsafeDrop n seq) ==+ (toList $ unsafeDrop n $ fromList seq)+#if MIN_VERSION_mono_traversable(1,0,4)+ describe "dropEnd" $ do+ prop "is equivalent to list" $+ \n (seq :: [Int]) ->+ (dropEnd n seq) ==+ (toList $ dropEnd n $ fromList seq)+#endif+ describe "partition" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (seq :: [Int]) ->+ (partition f seq) ==+ (let (a, b) = partition f (listToTrans seq) in (toList a, toList b))+ describe "uncons" $ do+ prop "is equivalent to list" $+ \(seq :: [Int]) ->+ (uncons seq) ==+ (second toList <$> uncons (listToTrans seq))+ describe "unsnoc" $ do+ prop "is equivalent to list" $+ \(seq :: [Int]) ->+ (unsnoc seq) ==+ (first toList <$> unsnoc (listToTrans seq))+ describe "filter" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (seq :: [Int]) ->+ (filter f seq) ==+ (toList $ filter f $ listToTrans seq)+ describe "filterM" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (seq :: [Int]) ->+ (filterM (f :: Int -> Maybe Bool) seq) ==+ (toList <$> filterM f (listToTrans seq))+ describe "replicate" $ do+ prop "is equivalent to list" $+ \n (a :: Int) ->+ (replicate n a) ==+ (toList $ replicate n a)+ describe "replicateM" $ do+ prop "is equivalent to list" $+ \n (ma :: Maybe Int) ->+ (replicateM n ma) ==+ (toList <$> replicateM n ma)+ describe "groupBy" $ do+ prop "is equivalent to list" $+ \f (seq :: [Int]) ->+ (groupBy (applyFun2 f) seq) ==+ (map toList $ groupBy (applyFun2 f) $ listToTrans seq)+ describe "groupAllOn" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (seq :: [Int]) ->+ (groupAllOn (f :: Int -> String) seq) ==+ (map toList $ groupAllOn f $ listToTrans seq)+ describe "subsequences" $ do+ modifyMaxSize (const 10) $ prop "is equivalent to list" $+ \(seq :: [Int]) ->+ (subsequences seq) ==+ (map toList $ subsequences $ listToTrans seq)+ describe "permutations" $ do+ modifyMaxSize (const 10) $ prop "is equivalent to list" $+ \(seq :: [Int]) ->+ (permutations seq) ==+ (map toList $ permutations $ listToTrans seq)+ describe "tailEx" $ do+ it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (tailEx seq)+ <*> tryEvaluate (toList $ tailEx $ listToTrans seq)+ describe "tailMay" $ do+ prop "is equivalent to list" $+ \(seq :: [Int]) ->+ (tailMay seq) ==+ (fmap toList $ tailMay $ listToTrans seq)+ describe "initEx" $ do+ it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (initEx seq)+ <*> tryEvaluate (toList $ initEx $ listToTrans seq)+ describe "initMay" $ do+ prop "is equivalent to list" $+ \(seq :: [Int]) ->+ (initMay seq) ==+ (fmap toList $ initMay $ listToTrans seq)+ describe "unsafeTail" $ do+ it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (unsafeTail seq)+ <*> tryEvaluate (toList $ unsafeTail $ listToTrans seq)+ describe "unsafeInit" $ do+ it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $+ exceptionableEq+ <$> tryEvaluate (unsafeInit seq)+ <*> tryEvaluate (toList $ unsafeInit $ listToTrans seq)+ describe "index" $ do+ prop "is equivalent to list" $+ \(seq :: [Int]) n ->+ (index seq n) ==+ (index (listToTrans seq) n)+ describe "indexEx" $ do+ it "is equivalent to list" $ again $ \(seq :: [Int]) n -> ioProperty $+ exceptionableEq <$> tryEvaluate (indexEx seq n) <*> tryEvaluate (indexEx (listToTrans seq) n)+ describe "unsafeIndex" $ do+ it "is equivalent to list" $ again $ \(seq :: [Int]) n -> ioProperty $+ exceptionableEq <$> tryEvaluate (unsafeIndex seq n) <*> tryEvaluate (unsafeIndex (listToTrans seq) n)++ describe "splitWhen" $ do+ prop "is equivalent to list" $+ \(Fun _ f) (seq :: [Int]) ->+ (splitWhen f seq) ==+ (fmap toList $ splitWhen f $ listToTrans seq)++listToTrans :: [a] -> Transaction a+listToTrans = fromList
transaction.cabal view
@@ -1,8 +1,8 @@ name: transaction-version: 0.1.0.0+version: 0.1.1.0 synopsis: Monadic representation of transactions. description:- Monadic representation of transactions.+ Monadic representation of transactions. Alike `List`, but can be declared with `do` notations. homepage: https://github.com/arowM/haskell-transaction#readme license: MIT license-file: LICENSE@@ -18,6 +18,7 @@ hs-source-dirs: src exposed-modules: Data.Transaction build-depends: base >= 4.9 && < 5+ , mono-traversable default-language: Haskell2010 default-extensions: OverloadedStrings , RecordWildCards@@ -31,6 +32,9 @@ hs-source-dirs: test main-is: Spec.hs build-depends: base+ , hspec >= 2.5 && < 3+ , mono-traversable+ , QuickCheck >= 2.11 && < 3 , transaction ghc-options: -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010