@@ -97,8 +97,11 @@ module Streamly.Internal.Data.StreamK.Type
9797 -- ** Specific Folds
9898 , drain
9999 , null
100+ , headNonEmpty
100101 , tail
102+ , tailNonEmpty
101103 , init
104+ , initNonEmpty
102105
103106 -- * Mapping
104107 , map
@@ -1811,14 +1814,42 @@ iterateMWith cns step = go
18111814 !next <- s
18121815 foldStreamShared st stp sng yld (return next `cns` go (step next))
18131816
1814−{-# INLINE headPartial #-}
1815−headPartial :: Monad m => StreamK m a -> m a
1816−headPartial = foldrM (\x _ -> return x) (error "head of nil")
1817+-- | head for non-empty streams, fails for empty stream case.
1818+--
1819+{-# INLINE headNonEmpty #-}
1820+headNonEmpty :: Monad m => StreamK m a -> m a
1821+headNonEmpty = foldrM (\x _ -> return x) (error "headNonEmpty: empty stream")
1822+
1823+-- | init for non-empty streams, fails for empty stream case.
1824+--
1825+-- See also 'init' for a non-partial version of this function..
1826+{-# INLINE initNonEmpty #-}
1827+initNonEmpty :: Stream m a -> Stream m a
1828+initNonEmpty = go0
1829+
1830+ where
1831+
1832+ go0 m = mkStream $ \st yld sng stp ->
1833+ let stop = error "initNonEmpty: Empty Stream."
1834+ single _ = stp
1835+ yieldk a r = foldStream st yld sng stp (go1 a r)
1836+ in foldStream st yieldk single stop m
1837+
1838+ go1 a r = mkStream $ \st yld sng stp ->
1839+ let stop = stp
1840+ single _ = sng a
1841+ yieldk a1 r1 = yld a (go1 a1 r1)
1842+ in foldStream st yieldk single stop r
18171843
1818−{-# INLINE tailPartial #-}
1819−tailPartial :: StreamK m a -> StreamK m a
1820−tailPartial m = mkStream $ \st yld sng stp ->
1821− let stop = error "tail of nil"
1844+-- | tail for non-empty streams, fails for empty stream case.
1845+--
1846+-- See also 'tail' for a non-partial version of this function..
1847+--
1848+-- Note: this is same as "drop 1" with error on empty stream.
1849+{-# INLINE tailNonEmpty #-}
1850+tailNonEmpty :: StreamK m a -> StreamK m a
1851+tailNonEmpty m = mkStream $ \st yld sng stp ->
1852+ let stop = error "tailNonEmpty: empty stream"
18221853 single _ = stp
18231854 yieldk _ r = foldStream st yld sng stp r
18241855 in foldStream st yieldk single stop m
@@ -1883,10 +1914,10 @@ mfix f = mkStream $ \st yld sng stp ->
18831914 where
18841915
18851916 -- fix the head element of the stream
1886− xs = fix (f . headPartial)
1917+ xs = fix (f . headNonEmpty)
18871918
18881919 -- now fix the tail recursively
1889− ys = mfix (tailPartial . f)
1920+ ys = mfix (tailNonEmpty . f)
18901921
18911922-------------------------------------------------------------------------------
18921923-- Conversions
@@ -1917,6 +1948,15 @@ uncons m =
19171948 yieldk a r = pure (Just (a, r))
19181949 in foldStream defState yieldk single stop m
19191950
1951+-- Note that this is not a StreamK -> StreamK because then we cannot handle the
1952+-- empty stream case without making this a partial function.
1953+--
1954+-- See tailNonEmpty as well above.
1955+
1956+-- | Same as:
1957+--
1958+-- >>> tail = fmap (fmap snd) StreamK.uncons
1959+--
19201960{-# INLINE tail #-}
19211961tail :: Applicative m => StreamK m a -> m (Maybe (StreamK m a))
19221962tail =
@@ -1925,9 +1965,14 @@ tail =
19251965 yieldk _ r = pure $ Just r
19261966 in foldStream defState yieldk single stop
19271967
1928−-- | Extract all but the last element of the stream, if any.
1968+-- Note that this is not a StreamK -> StreamK because then we cannot handle the
1969+-- empty stream case without making this a partial function.
19291970--
1930−-- Note: This will end up buffering the entire stream.
1971+-- XXX How do we implement unsnoc? Make StreamK a monad and return the
1972+-- remaining stream as a result value in the monad?
1973+
1974+-- | Extract all but the last element of the stream, if any. This will end up
1975+-- evaluating the last element as well to find out that it is last.
19311976--
19321977-- /Pre-release/
19331978{-# INLINE init #-}