-- maybe use package event-list instead.
module Data.DelayList (insert, decrease, DelayList) where

type DelayList a = [(Int, a)]

-- | Subtraction, but treat maxBound as infinity. i.e. maxBound -? x == maxBound
(-?) :: Int -> Int -> Int
Int
x -? :: Int -> Int -> Int
-? Int
y | Int
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
forall a. Bounded a => a
maxBound = Int
x
       | Bool
otherwise = Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
y

insert :: (Int, a) -> DelayList a -> DelayList a
insert :: (Int, a) -> DelayList a -> DelayList a
insert (Int
d, a
a) [] = [(Int
d, a
a)]
insert (Int
d, a
a) l :: DelayList a
l@(h :: (Int, a)
h@(Int
d', a
_):DelayList a
t)
       | Int
d Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
d' = (Int
d, a
a)(Int, a) -> DelayList a -> DelayList a
forall a. a -> [a] -> [a]
:DelayList a
t
       | Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<  Int
d' = (Int
d, a
a) (Int, a) -> DelayList a -> DelayList a
forall a. a -> [a] -> [a]
: Int -> DelayList a -> DelayList a
forall a. Int -> DelayList a -> DelayList a
decrease Int
d DelayList a
l
       -- d >  d'
       | Bool
otherwise = (Int, a)
h (Int, a) -> DelayList a -> DelayList a
forall a. a -> [a] -> [a]
: (Int, a) -> DelayList a -> DelayList a
forall a. (Int, a) -> DelayList a -> DelayList a
insert (Int
d Int -> Int -> Int
-? Int
d', a
a) DelayList a
t

decrease :: Int -> DelayList a -> DelayList a
decrease :: Int -> DelayList a -> DelayList a
decrease Int
_ [] = []
decrease Int
d l :: DelayList a
l@((Int
d',a
a):DelayList a
t)
    | Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = DelayList a
l
    | Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
d' = (Int
d' Int -> Int -> Int
-? Int
d, a
a)(Int, a) -> DelayList a -> DelayList a
forall a. a -> [a] -> [a]
:DelayList a
t
    -- d >= d'
    | Bool
otherwise = Int -> DelayList a -> DelayList a
forall a. Int -> DelayList a -> DelayList a
decrease (Int
d Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
d') DelayList a
t