{- | Module : Cookbook.Essential.Common Copyright : (c) 2015 by Nate Pisarski License : BSD3 Maintainer : nathanpisarski@gmail.com Stability : Stable Portability : Portable (Standalone - ghc) "global" functions for the entirety of the Cookbook library. Common is the potpourri of Cookbook, with no category except "everything uses me!" -} module Cookbook.Essential.Common where -- | Return a list starting at an index. Indices start at 0. sub :: (Eq a) => [a] -> Int -> [a] sub [] _ = [] sub x 0 = x sub (_:xs) c = sub xs (c - 1) -- | Find the occurrences of an element in a list. positions :: (Eq a) => [a] -> a -> [Int] positions x c = let y = zip x [0..(length x)] in find y where find y = [e | (d,e) <- y, d == c] -- | C-style wrapper for positions. Returns the first occurrence in a list, or -1 on notElem. pos :: (Eq a) => [a] -> a -> Int pos x c | c `notElem` x = -1 pos x c = let ans = positions x c in ((if (length ans) > 1 then (head . tail) else head) ans) -- | Reversal of map function. Chains calls of functions over a parameter, starting with head. apply :: [(a -> a)] -> a -> a apply [] c = c apply (f:fs) c = apply fs (f c) -- | Flatten a list one level. flt :: [[a]] -> [a] flt [] = [] flt (x:xs) = x ++ flt xs -- | Execute a function from the end of a list to the front. fromLast :: ([a] -> [a]) -> [a] -> [a] fromLast f c = rev $ f $ rev c where rev [] = [] -- Reimplementation of Md.rev rev (x:xs) = rev xs ++ [x] -- | After a certain number of an element, return the list. afterX :: (Eq a) => [a] -> a -> Int -> [a] afterX (x:xs) c t | t == 0 = x:xs | otherwise = if x == c then afterX xs c (pred t) else afterX xs c t -- | Internal implementation of "intersperse". iSp :: [a] -> a -> [a] iSp [] _ = [] iSp (x:xs) c = ([x] ++ [c]) ++ iSp xs c