{-|
Module      : Recalc.Univer.Internal
Description : List manipulation utility functions for manipulating the sheet order.
-}
module Recalc.Univer.Internal where

-- | updates an existing value in a list (first match)
updateList :: Eq a => a -> a -> [a] -> [a]
updateList :: forall a. Eq a => a -> a -> [a] -> [a]
updateList a
old a
new (a
v : [a]
vs)
  | a
v a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
old = a
new a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
vs
  | Bool
otherwise = a
v a -> [a] -> [a]
forall a. a -> [a] -> [a]
: a -> a -> [a] -> [a]
forall a. Eq a => a -> a -> [a] -> [a]
updateList a
old a
new [a]
vs
updateList a
_ a
_ [a]
_ = []

-- | removes the first occurrence of a key in an association list
removeAt :: Eq k => k -> [(k, a)] -> [(k, a)]
removeAt :: forall k a. Eq k => k -> [(k, a)] -> [(k, a)]
removeAt k
k ((k, a)
el : [(k, a)]
kvs)
  | k
k k -> k -> Bool
forall a. Eq a => a -> a -> Bool
== (k, a) -> k
forall a b. (a, b) -> a
fst (k, a)
el = [(k, a)]
kvs
  | Bool
otherwise = (k, a)
el (k, a) -> [(k, a)] -> [(k, a)]
forall a. a -> [a] -> [a]
: k -> [(k, a)] -> [(k, a)]
forall k a. Eq k => k -> [(k, a)] -> [(k, a)]
removeAt k
k [(k, a)]
kvs
removeAt k
_ [] = []

-- | inserts an element at a specified index
insertAt :: Int -> a -> [a] -> [a]
insertAt :: forall a. Int -> a -> [a] -> [a]
insertAt Int
i a
el [a]
xs =
  let ([a]
hd, [a]
tl) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
i [a]
xs in [a]
hd [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ a
el a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
tl

-- | moves an element from one index to another
moveList :: (Eq a, Show a) => Int -> Int -> [a] -> [a]
moveList :: forall a. (Eq a, Show a) => Int -> Int -> [a] -> [a]
moveList Int
from Int
to [a]
xs
  | Int
from Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
to
  , let
      ([a]
us, [a]
vs) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
from [a]
xs
      ([a]
as, [a]
bs) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt (Int
to Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
from Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [a]
vs =
      [a]
us [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a] -> [a]
forall a. HasCallStack => [a] -> [a]
tail [a]
as [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a] -> a
forall a. HasCallStack => [a] -> a
head [a]
as a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
bs
  | Int
to Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
from
  , let
      ([a]
us, [a]
vs) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
to [a]
xs
      ([a]
as, [a]
bs) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt (Int
from Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
to) [a]
vs =
      [a]
us [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a] -> a
forall a. HasCallStack => [a] -> a
head [a]
bs a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
as [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a] -> [a]
forall a. HasCallStack => [a] -> [a]
tail [a]
bs
  | Bool
otherwise = [a]
xs