hydra-kernel-0.16.0: src/main/haskell/Hydra/Haskell/Lib/Lists.hs
-- | Haskell implementations of hydra.lib.lists primitives
module Hydra.Haskell.Lib.Lists where
import Hydra.Util
import Hydra.Core
import Hydra.Graph
import qualified Hydra.Dsl.Terms as Terms
import qualified Data.List as L
-- | Apply a list of functions to a list of values (applicative style).
apply :: [a -> b] -> [a] -> [b]
apply = (<*>)
-- | Apply a function that returns lists to each element and flatten results.
bind :: [a] -> (a -> [b]) -> [b]
bind = (>>=)
-- | Concatenate a list of lists.
concat :: [[a]] -> [a]
concat = L.concat
-- | Concatenate two lists.
concat2 :: [a] -> [a] -> [a]
concat2 l1 l2 = l1 ++ l2
-- | Prepend a value to a list.
cons :: a -> [a] -> [a]
cons = (:)
-- | Drop the first n elements from a list.
drop :: Int -> [a] -> [a]
drop = L.drop
-- | Drop elements from the beginning of a list while predicate is true.
dropWhile :: (a -> Bool) -> [a] -> [a]
dropWhile = L.dropWhile
-- | Check if an element is in a list.
elem :: Eq a => a -> [a] -> Bool
elem = L.elem
-- | Filter a list based on a predicate.
filter :: (a -> Bool) -> [a] -> [a]
filter = L.filter
-- | Find the first element matching a predicate.
find :: (a -> Bool) -> [a] -> Maybe a
find = L.find
-- | Fold a list from the left.
-- Strict left fold. Lazy foldl can pile up thunks for accumulator types
-- that are field-update records (e.g. PythonModuleMetadata in
-- Hydra.Python.Coder.extendMetaForTerm), causing pathological wallclock
-- in the Python coder's gatherMetadata pass. Use foldl' to evaluate
-- each accumulator step strictly.
foldl :: (b -> a -> b) -> b -> [a] -> b
foldl = L.foldl'
-- | Fold a list from the right.
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr = L.foldr
-- | Group consecutive equal elements.
group :: Eq a => [a] -> [[a]]
group = L.group
-- | Intercalate a list of lists with a separator list between each.
intercalate :: [a] -> [[a]] -> [a]
intercalate = L.intercalate
-- | Intersperse a value between elements of a list.
intersperse :: a -> [a] -> [a]
intersperse = L.intersperse
-- | Get the length of a list.
length :: [a] -> Int
length = L.length
-- | Map a function over a list.
map :: (a -> b) -> [a] -> [b]
map = fmap
-- | Get the element at a specified index in a list, returning Nothing if out of bounds.
maybeAt :: Int -> [a] -> Maybe a
maybeAt i l
| i < 0 || i >= L.length l = Nothing
| otherwise = Just (l !! i)
-- | Get the first element of a list, returning Nothing if the list is empty.
maybeHead :: [a] -> Maybe a
maybeHead [] = Nothing
maybeHead (x:_) = Just x
-- | Return all elements except the last one, returning Nothing if the list is empty.
maybeInit :: [a] -> Maybe [a]
maybeInit [] = Nothing
maybeInit xs = Just (L.init xs)
-- | Get the last element of a list, returning Nothing if the list is empty.
maybeLast :: [a] -> Maybe a
maybeLast [] = Nothing
maybeLast xs = Just (L.last xs)
-- | Get all elements of a list except the first, returning Nothing if the list is empty.
maybeTail :: [a] -> Maybe [a]
maybeTail [] = Nothing
maybeTail (_:xs) = Just xs
-- | Remove duplicate elements from a list.
nub :: Eq a => [a] -> [a]
nub = L.nub
-- | Check if a list is empty.
null :: [a] -> Bool
null = L.null
-- | Partition a list into elements that satisfy a predicate and elements that do not.
partition :: (a -> Bool) -> [a] -> ([a], [a])
partition = L.partition
-- | Create a list with a single element.
pure :: a -> [a]
pure e = [e]
-- | Create a list with n copies of a value.
replicate :: Int -> a -> [a]
replicate = L.replicate
-- | Reverse a list.
reverse :: [a] -> [a]
reverse = L.reverse
-- | Create a single-element list.
singleton :: a -> [a]
singleton e = [e]
-- | Sort a list.
sort :: Ord a => [a] -> [a]
sort = L.sort
-- | Sort a list based on a key function.
sortOn :: Ord b => (a -> b) -> [a] -> [a]
sortOn = L.sortOn
-- | Split a list at the first element where predicate fails.
span :: (a -> Bool) -> [a] -> ([a], [a])
span = L.span
-- | Take the first n elements from a list.
take :: Int -> [a] -> [a]
take = L.take
-- | Transpose a list of lists.
transpose :: [[a]] -> [[a]]
transpose = L.transpose
-- | Decompose a list into its head and tail, returning Nothing if the list is empty.
uncons :: [a] -> Maybe (a, [a])
uncons [] = Nothing
uncons (x:xs) = Just (x, xs)
-- | Zip two lists into pairs.
zip :: [a] -> [b] -> [(a, b)]
zip = L.zip
-- | Zip two lists with a combining function.
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith = L.zipWith