{-# LANGUAGE CPP #-}
{-# LANGUAGE ExistentialQuantification #-}
module Unicode.Internal.Unfold
( Unfold(..)
, Step(..)
, toList
) where
import GHC.Base (build)
#if MIN_VERSION_base(4,12,0)
data Unfold a b = forall s. Unfold
(s -> Step s b)
(a -> Step s b)
#else
data Unfold a b =
forall s. Unfold (s -> Step s b) (a -> Step s b)
#endif
data Step s a
= Yield !a !s
| Stop
instance Functor (Step s) where
{-# INLINE fmap #-}
fmap :: forall a b. (a -> b) -> Step s a -> Step s b
fmap a -> b
f (Yield a
x s
s) = b -> s -> Step s b
forall s a. a -> s -> Step s a
Yield (a -> b
f a
x) s
s
fmap a -> b
_ Step s a
Stop = Step s b
forall s a. Step s a
Stop
{-# INLINE toList #-}
toList :: Unfold a a -> a -> [a]
toList :: forall a. Unfold a a -> a -> [a]
toList (Unfold s -> Step s a
step a -> Step s a
inject) a
input =
case a -> Step s a
inject a
input of
Step s a
Stop -> [a
input]
Yield a
b s
s0 -> a
b a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (forall b. (a -> b -> b) -> b -> b) -> [a]
forall a. (forall b. (a -> b -> b) -> b -> b) -> [a]
build
( \a -> b -> b
c b
n ->
let go :: s -> b
go s
s = case s -> Step s a
step s
s of
Yield a
a s
s' -> a
a a -> b -> b
`c` s -> b
go s
s'
Step s a
Stop -> b
n
in s -> b
go s
s0
)