module Tokstyle.Worklist (
    Worklist,
    empty,
    fromList,
    push,
    pushList,
    pop,
    toList
) where

import qualified Data.Foldable as F
import           Data.Sequence (Seq, (|>))
import qualified Data.Sequence as Seq

newtype Worklist a = Worklist (Seq a)
    deriving (Int -> Worklist a -> ShowS
[Worklist a] -> ShowS
Worklist a -> String
(Int -> Worklist a -> ShowS)
-> (Worklist a -> String)
-> ([Worklist a] -> ShowS)
-> Show (Worklist a)
forall a. Show a => Int -> Worklist a -> ShowS
forall a. Show a => [Worklist a] -> ShowS
forall a. Show a => Worklist a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Worklist a] -> ShowS
$cshowList :: forall a. Show a => [Worklist a] -> ShowS
show :: Worklist a -> String
$cshow :: forall a. Show a => Worklist a -> String
showsPrec :: Int -> Worklist a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Worklist a -> ShowS
Show, Worklist a -> Worklist a -> Bool
(Worklist a -> Worklist a -> Bool)
-> (Worklist a -> Worklist a -> Bool) -> Eq (Worklist a)
forall a. Eq a => Worklist a -> Worklist a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Worklist a -> Worklist a -> Bool
$c/= :: forall a. Eq a => Worklist a -> Worklist a -> Bool
== :: Worklist a -> Worklist a -> Bool
$c== :: forall a. Eq a => Worklist a -> Worklist a -> Bool
Eq)

empty :: Worklist a
empty :: Worklist a
empty = Seq a -> Worklist a
forall a. Seq a -> Worklist a
Worklist Seq a
forall a. Seq a
Seq.empty

fromList :: [a] -> Worklist a
fromList :: [a] -> Worklist a
fromList = Seq a -> Worklist a
forall a. Seq a -> Worklist a
Worklist (Seq a -> Worklist a) -> ([a] -> Seq a) -> [a] -> Worklist a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Seq a
forall a. [a] -> Seq a
Seq.fromList

push :: a -> Worklist a -> Worklist a
push :: a -> Worklist a -> Worklist a
push a
a (Worklist Seq a
s) = Seq a -> Worklist a
forall a. Seq a -> Worklist a
Worklist (Seq a
s Seq a -> a -> Seq a
forall a. Seq a -> a -> Seq a
|> a
a)

pushList :: [a] -> Worklist a -> Worklist a
pushList :: [a] -> Worklist a -> Worklist a
pushList [a]
l (Worklist Seq a
s) = Seq a -> Worklist a
forall a. Seq a -> Worklist a
Worklist (Seq a
s Seq a -> Seq a -> Seq a
forall a. Semigroup a => a -> a -> a
<> [a] -> Seq a
forall a. [a] -> Seq a
Seq.fromList [a]
l)

pop :: Worklist a -> Maybe (a, Worklist a)
pop :: Worklist a -> Maybe (a, Worklist a)
pop (Worklist Seq a
s) =
    case Seq a -> ViewL a
forall a. Seq a -> ViewL a
Seq.viewl Seq a
s of
        ViewL a
Seq.EmptyL  -> Maybe (a, Worklist a)
forall a. Maybe a
Nothing
        a
a Seq.:< Seq a
s' -> (a, Worklist a) -> Maybe (a, Worklist a)
forall a. a -> Maybe a
Just (a
a, Seq a -> Worklist a
forall a. Seq a -> Worklist a
Worklist Seq a
s')

toList :: Worklist a -> [a]
toList :: Worklist a -> [a]
toList (Worklist Seq a
s) = Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList Seq a
s