module Stack (module Stack, module X) where
import Data.Maybe (fromJust)
import Data.Foldable as X (toList)
import Data.Set.Ordered (OSet, (|<))
import qualified Data.Set.Ordered as OS

type Stack a = OSet a

empty :: Stack a
empty :: forall a. Stack a
empty = forall a. Stack a
OS.empty

singleton :: a -> Stack a
singleton :: forall a. a -> Stack a
singleton = forall a. a -> Stack a
OS.singleton

insert :: Ord a => a -> Stack a -> Stack a
insert :: forall a. Ord a => a -> Stack a -> Stack a
insert = forall a. Ord a => a -> Stack a -> Stack a
(|<)

removeLast :: Ord a => Stack a -> Stack a
removeLast :: forall a. Ord a => Stack a -> Stack a
removeLast Stack a
s = forall a. Ord a => a -> Stack a -> Stack a
OS.delete (forall a. Stack a -> a
Stack.last Stack a
s) Stack a
s

head :: Stack a -> a
head :: forall a. Stack a -> a
head = (forall a. Stack a -> Int -> a
`unsafeElemAt` Int
0)

safeHead :: Stack a -> Maybe a
safeHead :: forall a. Stack a -> Maybe a
safeHead = (forall a. Stack a -> Int -> Maybe a
`elemAt` Int
0)

last :: Stack a -> a
last :: forall a. Stack a -> a
last Stack a
s = Stack a
s forall a. Stack a -> Int -> a
`unsafeElemAt` (forall a. Stack a -> Int
Stack.size Stack a
s forall a. Num a => a -> a -> a
- Int
1)

pop :: Ord a => Stack a -> Stack a
pop :: forall a. Ord a => Stack a -> Stack a
pop Stack a
s = forall a. Ord a => a -> Stack a -> Stack a
OS.delete (forall a. Stack a -> a
Stack.head Stack a
s) Stack a
s

popWithInfo :: Ord a => Stack a -> (Stack a, a, a)
popWithInfo :: forall a. Ord a => Stack a -> (Stack a, a, a)
popWithInfo Stack a
s = let
  top :: a
top  = forall a. Stack a -> a
Stack.head Stack a
s
  s' :: Stack a
s'   = forall a. Ord a => a -> Stack a -> Stack a
OS.delete a
top Stack a
s
  top' :: a
top' = forall a. Stack a -> a
Stack.head Stack a
s' in
    (Stack a
s', a
top, a
top')

tail :: Ord a => Stack a -> [a]
tail :: forall a. Ord a => Stack a -> [a]
tail = forall (t :: * -> *) a. Foldable t => t a -> [a]
toList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => Stack a -> Stack a
pop

elemAt :: Stack a -> Int -> Maybe a
elemAt :: forall a. Stack a -> Int -> Maybe a
elemAt = forall a. Stack a -> Int -> Maybe a
OS.elemAt

takeStack :: Ord a => Int -> Stack a -> Stack a
takeStack :: forall a. Ord a => Int -> Stack a -> Stack a
takeStack Int
n = forall a. Ord a => [a] -> Stack a
fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> [a] -> [a]
take Int
n forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> [a]
toList

unsafeElemAt :: Stack a -> Int -> a
unsafeElemAt :: forall a. Stack a -> Int -> a
unsafeElemAt Stack a
s = forall a. HasCallStack => Maybe a -> a
fromJust forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Stack a -> Int -> Maybe a
OS.elemAt Stack a
s

fromList :: Ord a => [a] -> Stack a
fromList :: forall a. Ord a => [a] -> Stack a
fromList = forall a. Ord a => [a] -> Stack a
OS.fromList

-- toList :: Ord a => Stack a -> [a]

-- toList = toList


size :: Stack a -> Int
size :: forall a. Stack a -> Int
size = forall a. Stack a -> Int
OS.size