packages feed

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 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