Change elimination ops to use monomoprhic SerialT

This commit is contained in:
Harendra Kumar 2018-04-18 11:18:08 +05:30
parent 38d21d5193
commit c463d1634c
3 changed files with 35 additions and 37 deletions

View File

@ -16,14 +16,16 @@
different behavior for each type. See the documentation for more details. To different behavior for each type. See the documentation for more details. To
adapt to this change replace any usage of `<|>` with `parallel` and adapt to this change replace any usage of `<|>` with `parallel` and
`empty` with `nil`. `empty` with `nil`.
* Streams now default to the `SerialT` type unless explicitly specified using a * Stream type now defaults to the `SerialT` type unless explicitly specified
type combinator. This also means that you do not have to explicitly specify a using a type combinator or a monomorphic type. This change reduces puzzling
stream type now, the default will be used. This changes reduces puzzling type type errors for beginners. It includes the following two changes:
errors for beginners. It includes the following two changes:
* Change the type of all stream elimination functions to `SerialT`. This * Change the type of all stream elimination functions to `SerialT`. This
makes sure that the stream type is always fixed at all exits. makes sure that the stream type is always fixed at all exits.
* Change the type combinators to only fix the argument stream type and * Change the type combinators to only fix the argument stream type and
the resulting stream type remains polymorphic. the resulting stream type remains polymorphic.
Stream types may have to be changed or type combinators may have to added or
removed to adapt to this change.
* Change the type of `foldrM` to make it consistent with `foldrM` in base. * Change the type of `foldrM` to make it consistent with `foldrM` in base.
### Deprecations ### Deprecations
@ -50,7 +52,7 @@
* `foldl'` strict left fold * `foldl'` strict left fold
* `foldlM'` strict left fold with a monadic fold function * `foldlM'` strict left fold with a monadic fold function
* `append` run two streams serially one after the other * `append` run two streams serially one after the other
* `parallel` run two streams in parallel * `parallel` run two streams in parallel (replaces `<|>`)
## 0.1.2 ## 0.1.2

View File

@ -174,7 +174,7 @@ fromHandle h = fromStream go
-- >> runIdentity $ foldr (:) [] (serially $ fromFoldable [1,2,3]) -- >> runIdentity $ foldr (:) [] (serially $ fromFoldable [1,2,3])
-- [1,2,3] -- [1,2,3]
-- @ -- @
foldr :: (IsStream t, Monad m) => (a -> b -> b) -> b -> t m a -> m b foldr :: Monad m => (a -> b -> b) -> b -> SerialT m a -> m b
foldr step acc m = go (toStream m) foldr step acc m = go (toStream m)
where where
go m1 = go m1 =
@ -191,7 +191,7 @@ foldr step acc m = go (toStream m)
-- [1,2,3] -- [1,2,3]
-- @ -- @
{-# INLINE foldrM #-} {-# INLINE foldrM #-}
foldrM :: (IsStream t, Monad m) => (a -> b -> m b) -> b -> t m a -> m b foldrM :: Monad m => (a -> b -> m b) -> b -> SerialT m a -> m b
foldrM step acc m = go (toStream m) foldrM step acc m = go (toStream m)
where where
go m1 = go m1 =
@ -233,8 +233,7 @@ scanl' step begin m = scanx step begin id m
-- argument) to the folded value at the end. This is designed to work with the -- argument) to the folded value at the end. This is designed to work with the
-- @foldl@ library. The suffix @x@ is a mnemonic for extraction. -- @foldl@ library. The suffix @x@ is a mnemonic for extraction.
{-# INLINE foldx #-} {-# INLINE foldx #-}
foldx :: (IsStream t, Monad m) foldx :: Monad m => (x -> a -> x) -> x -> (x -> b) -> SerialT m a -> m b
=> (x -> a -> x) -> x -> (x -> b) -> t m a -> m b
foldx step begin done m = get $ go (toStream m) begin foldx step begin done m = get $ go (toStream m) begin
where where
{-# NOINLINE get #-} {-# NOINLINE get #-}
@ -257,19 +256,17 @@ foldx step begin done m = get $ go (toStream m) begin
in (S.runStream m1) Nothing stop yield in (S.runStream m1) Nothing stop yield
{-# DEPRECATED foldl "Please use foldx instead." #-} {-# DEPRECATED foldl "Please use foldx instead." #-}
foldl :: (IsStream t, Monad m) foldl :: Monad m => (x -> a -> x) -> x -> (x -> b) -> SerialT m a -> m b
=> (x -> a -> x) -> x -> (x -> b) -> t m a -> m b
foldl = foldx foldl = foldx
-- | Strict left associative fold. -- | Strict left associative fold.
{-# INLINE foldl' #-} {-# INLINE foldl' #-}
foldl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> m b foldl' :: Monad m => (b -> a -> b) -> b -> SerialT m a -> m b
foldl' step begin m = foldx step begin id m foldl' step begin m = foldx step begin id m
-- XXX replace the recursive "go" with explicit continuations. -- XXX replace the recursive "go" with explicit continuations.
-- | Like 'foldx', but with a monadic step function. -- | Like 'foldx', but with a monadic step function.
foldxM :: (IsStream t, Monad m) foldxM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> SerialT m a -> m b
=> (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> m b
foldxM step begin done m = go begin (toStream m) foldxM step begin done m = go begin (toStream m)
where where
go !acc m1 = go !acc m1 =
@ -279,18 +276,17 @@ foldxM step begin done m = go begin (toStream m)
in (S.runStream m1) Nothing stop yield in (S.runStream m1) Nothing stop yield
{-# DEPRECATED foldlM "Please use foldxM instead." #-} {-# DEPRECATED foldlM "Please use foldxM instead." #-}
foldlM :: (IsStream t, Monad m) foldlM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> SerialT m a -> m b
=> (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> m b
foldlM = foldxM foldlM = foldxM
-- | Like 'foldl'' but with a monadic step function. -- | Like 'foldl'' but with a monadic step function.
foldlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> m b foldlM' :: Monad m => (b -> a -> m b) -> b -> SerialT m a -> m b
foldlM' step begin m = foldxM step (return begin) return m foldlM' step begin m = foldxM step (return begin) return m
-- | Decompose a stream into its head and tail. If the stream is empty, returns -- | Decompose a stream into its head and tail. If the stream is empty, returns
-- 'Nothing'. If the stream is non-empty, returns 'Just (a, ma)', where 'a' is -- 'Nothing'. If the stream is non-empty, returns 'Just (a, ma)', where 'a' is
-- the head of the stream and 'ma' its tail. -- the head of the stream and 'ma' its tail.
uncons :: (IsStream t, Monad m) => t m a -> m (Maybe (a, t m a)) uncons :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (a, t m a))
uncons m = uncons m =
let stop = return Nothing let stop = return Nothing
yield a Nothing = return (Just (a, nil)) yield a Nothing = return (Just (a, nil))
@ -298,7 +294,7 @@ uncons m =
in (S.runStream (toStream m)) Nothing stop yield in (S.runStream (toStream m)) Nothing stop yield
-- | Write a stream of Strings to an IO Handle. -- | Write a stream of Strings to an IO Handle.
toHandle :: (IsStream t, MonadIO m) => IO.Handle -> t m String -> m () toHandle :: MonadIO m => IO.Handle -> SerialT m String -> m ()
toHandle h m = go (toStream m) toHandle h m = go (toStream m)
where where
go m1 = go m1 =
@ -376,7 +372,7 @@ dropWhile p m = fromStream $ go (toStream m)
in (S.runStream m1) ctx stp yield in (S.runStream m1) ctx stp yield
-- | Determine whether all elements of a stream satisfy a predicate. -- | Determine whether all elements of a stream satisfy a predicate.
all :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool all :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
all p m = go (toStream m) all p m = go (toStream m)
where where
go m1 = go m1 =
@ -387,7 +383,7 @@ all p m = go (toStream m)
in (S.runStream m1) Nothing (return True) yield in (S.runStream m1) Nothing (return True) yield
-- | Determine whether any of the elements of a stream satisfy a predicate. -- | Determine whether any of the elements of a stream satisfy a predicate.
any :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool any :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
any p m = go (toStream m) any p m = go (toStream m)
where where
go m1 = go m1 =
@ -398,22 +394,22 @@ any p m = go (toStream m)
in (S.runStream m1) Nothing (return False) yield in (S.runStream m1) Nothing (return False) yield
-- | Determine the sum of all elements of a stream of numbers -- | Determine the sum of all elements of a stream of numbers
sum :: (IsStream t, Monad m, Num a) => t m a -> m a sum :: (Monad m, Num a) => SerialT m a -> m a
sum = foldl (+) 0 id sum = foldl (+) 0 id
-- | Determine the product of all elements of a stream of numbers -- | Determine the product of all elements of a stream of numbers
product :: (IsStream t, Monad m, Num a) => t m a -> m a product :: (Monad m, Num a) => SerialT m a -> m a
product = foldl (*) 1 id product = foldl (*) 1 id
-- | Extract the first element of the stream, if any. -- | Extract the first element of the stream, if any.
head :: (IsStream t, Monad m) => t m a -> m (Maybe a) head :: Monad m => SerialT m a -> m (Maybe a)
head m = head m =
let stop = return Nothing let stop = return Nothing
yield a _ = return (Just a) yield a _ = return (Just a)
in (S.runStream (toStream m)) Nothing stop yield in (S.runStream (toStream m)) Nothing stop yield
-- | Extract all but the first element of the stream, if any. -- | Extract all but the first element of the stream, if any.
tail :: (IsStream t, Monad m) => t m a -> m (Maybe (t m a)) tail :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (t m a))
tail m = tail m =
let stop = return Nothing let stop = return Nothing
yield _ Nothing = return $ Just nil yield _ Nothing = return $ Just nil
@ -422,18 +418,18 @@ tail m =
-- | Extract the last element of the stream, if any. -- | Extract the last element of the stream, if any.
{-# INLINE last #-} {-# INLINE last #-}
last :: (IsStream t, Monad m) => t m a -> m (Maybe a) last :: Monad m => SerialT m a -> m (Maybe a)
last = foldl (\_ y -> Just y) Nothing id last = foldl (\_ y -> Just y) Nothing id
-- | Determine whether the stream is empty. -- | Determine whether the stream is empty.
null :: (IsStream t, Monad m) => t m a -> m Bool null :: Monad m => SerialT m a -> m Bool
null m = null m =
let stop = return True let stop = return True
yield _ _ = return False yield _ _ = return False
in (S.runStream (toStream m)) Nothing stop yield in (S.runStream (toStream m)) Nothing stop yield
-- | Determine whether an element is present in the stream. -- | Determine whether an element is present in the stream.
elem :: (IsStream t, Monad m, Eq a) => a -> t m a -> m Bool elem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
elem e m = go (toStream m) elem e m = go (toStream m)
where where
go m1 = go m1 =
@ -443,7 +439,7 @@ elem e m = go (toStream m)
in (S.runStream m1) Nothing stop yield in (S.runStream m1) Nothing stop yield
-- | Determine whether an element is not present in the stream. -- | Determine whether an element is not present in the stream.
notElem :: (IsStream t, Monad m, Eq a) => a -> t m a -> m Bool notElem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
notElem e m = go (toStream m) notElem e m = go (toStream m)
where where
go m1 = go m1 =
@ -453,7 +449,7 @@ notElem e m = go (toStream m)
in (S.runStream m1) Nothing stop yield in (S.runStream m1) Nothing stop yield
-- | Determine the length of the stream. -- | Determine the length of the stream.
length :: (IsStream t, Monad m) => t m a -> m Int length :: Monad m => SerialT m a -> m Int
length = foldl (\n _ -> n + 1) 0 id length = foldl (\n _ -> n + 1) 0 id
-- | Returns the elements of the stream in reverse order. -- | Returns the elements of the stream in reverse order.
@ -471,7 +467,7 @@ reverse m = fromStream $ go Nothing (toStream m)
-- XXX replace the recursive "go" with continuation -- XXX replace the recursive "go" with continuation
-- | Determine the minimum element in a stream. -- | Determine the minimum element in a stream.
minimum :: (IsStream t, Monad m, Ord a) => t m a -> m (Maybe a) minimum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
minimum m = go Nothing (toStream m) minimum m = go Nothing (toStream m)
where where
go r m1 = go r m1 =
@ -486,7 +482,7 @@ minimum m = go Nothing (toStream m)
-- XXX replace the recursive "go" with continuation -- XXX replace the recursive "go" with continuation
-- | Determine the maximum element in a stream. -- | Determine the maximum element in a stream.
maximum :: (IsStream t, Monad m, Ord a) => t m a -> m (Maybe a) maximum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
maximum m = go Nothing (toStream m) maximum m = go Nothing (toStream m)
where where
go r m1 = go r m1 =
@ -519,7 +515,7 @@ mapM f m = fromStream $ go (toStream m)
-- | Apply a monadic action to each element of the stream and discard the -- | Apply a monadic action to each element of the stream and discard the
-- output of the action. -- output of the action.
mapM_ :: (IsStream t, Monad m) => (a -> m b) -> t m a -> m () mapM_ :: Monad m => (a -> m b) -> SerialT m a -> m ()
mapM_ f m = go (toStream m) mapM_ f m = go (toStream m)
where where
go m1 = go m1 =

View File

@ -82,8 +82,8 @@ eliminateOp constr listOp op a =
elemOp elemOp
:: ([Word8] -> t IO Word8) :: ([Word8] -> t IO Word8)
-> (t IO Word8 -> t IO Word8) -> (t IO Word8 -> SerialT IO Word8)
-> (Word8 -> t IO Word8 -> IO Bool) -> (Word8 -> SerialT IO Word8 -> IO Bool)
-> (Word8 -> [Word8] -> Bool) -> (Word8 -> [Word8] -> Bool)
-> (Word8, [Word8]) -> (Word8, [Word8])
-> Property -> Property
@ -160,7 +160,7 @@ eliminationOps
:: IsStream t :: IsStream t
=> ([Int] -> t IO Int) => ([Int] -> t IO Int)
-> String -> String
-> (t IO Int -> t IO Int) -> (t IO Int -> SerialT IO Int)
-> Spec -> Spec
eliminationOps constr desc t = do eliminationOps constr desc t = do
-- Elimination -- Elimination
@ -196,7 +196,7 @@ transformOpsWord8
:: IsStream t :: IsStream t
=> ([Word8] -> t IO Word8) => ([Word8] -> t IO Word8)
-> String -> String
-> (t IO Word8 -> t IO Word8) -> (t IO Word8 -> SerialT IO Word8)
-> Spec -> Spec
transformOpsWord8 constr desc t = do transformOpsWord8 constr desc t = do
prop (desc ++ " elem") $ elemOp constr t A.elem elem prop (desc ++ " elem") $ elemOp constr t A.elem elem