{-# LANGUAGE BangPatterns #-}
module Slist.Maybe
( maybeToSlist
, slistToMaybe
, catMaybes
, mapMaybe
, slistWith
) where
import Data.Bifunctor (second)
import Slist.Size (Size (..))
import Slist.Type (Slist (..), cons, one)
import qualified Data.Maybe as M
maybeToSlist :: Maybe a -> Slist a
maybeToSlist :: forall a. Maybe a -> Slist a
maybeToSlist = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty forall a. a -> Slist a
one
{-# INLINE maybeToSlist #-}
slistToMaybe :: Slist a -> Maybe a
slistToMaybe :: forall a. Slist a -> Maybe a
slistToMaybe = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just) forall a. Maybe a
Nothing
{-# INLINE slistToMaybe #-}
catMaybes :: Slist (Maybe a) -> Slist a
catMaybes :: forall a. Slist (Maybe a) -> Slist a
catMaybes = forall b a. (a -> Maybe b) -> Slist a -> Slist b
mapMaybe forall a. a -> a
id
{-# INLINE catMaybes #-}
mapMaybe :: forall b a . (a -> Maybe b) -> Slist a -> Slist b
mapMaybe :: forall b a. (a -> Maybe b) -> Slist a -> Slist b
mapMaybe a -> Maybe b
_ (Slist [] Size
_) = forall a. Monoid a => a
mempty
mapMaybe a -> Maybe b
f (Slist [a]
xs Size
Infinity) = forall a. [a] -> Size -> Slist a
Slist (forall a b. (a -> Maybe b) -> [a] -> [b]
M.mapMaybe a -> Maybe b
f [a]
xs) Size
Infinity
mapMaybe a -> Maybe b
f (Slist (a
x:[a]
xs) Size
n) = case a -> Maybe b
f a
x of
Maybe b
Nothing -> Slist b
rest
Just b
r -> forall a. a -> Slist a -> Slist a
cons b
r Slist b
rest
where
rest :: Slist b
rest :: Slist b
rest = forall b a. (a -> Maybe b) -> Slist a -> Slist b
mapMaybe a -> Maybe b
f (forall a. [a] -> Size -> Slist a
Slist [a]
xs (Size
n forall a. Num a => a -> a -> a
- Size
1))
{-# NOINLINE [1] mapMaybe #-}
slistWith :: forall b a . (a -> Maybe b) -> [a] -> Slist b
slistWith :: forall b a. (a -> Maybe b) -> [a] -> Slist b
slistWith a -> Maybe b
f [a]
l = let (Int
n, [b]
sl) = Int -> [a] -> (Int, [b])
go Int
0 [a]
l in forall a. [a] -> Size -> Slist a
Slist [b]
sl (Int -> Size
Size Int
n)
where
go :: Int -> [a] -> (Int, [b])
go :: Int -> [a] -> (Int, [b])
go !Int
accSize [] = (Int
accSize, [])
go !Int
accSize (a
x:[a]
xs) = case a -> Maybe b
f a
x of
Maybe b
Nothing -> Int -> [a] -> (Int, [b])
go Int
accSize [a]
xs
Just b
r -> forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (b
rforall a. a -> [a] -> [a]
:) forall a b. (a -> b) -> a -> b
$ Int -> [a] -> (Int, [b])
go (Int
accSize forall a. Num a => a -> a -> a
+ Int
1) [a]
xs