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

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