{- | Module : Cookbook.Ingredients.Lists.Access Copyright : (c) 2014 by Nate Pisarski License : BSD3 Maintainer : nathanpisarski@gmail.com Stability : Stable Portability : Portable (Cookbook) Library for accessing the information from a list. Modify and Access are six in one and half-dozen in the other in a purely functional language, but the overall theme is this: Access is for functions which return portions of the list, or information about a list. Modify is the library which transforms a list. -} module Cookbook.Ingredients.Lists.Access where import qualified Cookbook.Ingredients.Functional.Break as Br import qualified Cookbook.Essential.Common as Cm -- | Counts the occurrences an element has within a list. count :: (Eq a) => [a] -> a -> Int count x c = sum $ Br.btr (==c) (1,0) x -- | Checks to see if a list is a sub-list of the list. contains :: (Eq a) => [a] -> [a] -> Bool contains [] _ = False contains x c = (part x == c) || contains (tail x) c where part = take (length c) -- | QuickSort implementation. Sorts a list of data quickly? qsort :: (Ord a) => [a] -> [a] -- AKA Kenyan Sort qsort [] = [] qsort (x:xs) = lessT ++ [x] ++ greatT where (lessT,greatT) = (qsort $ filter (<=x) xs,qsort $filter (>x) xs) -- | Safe implementation of !!. Uses maybe instead of error. pull :: [a] -> Int -> Maybe a pull _ c | c < 0 = Nothing pull [] _ = Nothing pull (x:xs) c = if c == 0 then Just x else pull xs $ c - 1 -- | Referrential positioning. Find the position of an element in the first list, and return the element from the second list of the same position. In the event that the second list is shorter than the position where the element is found in the first list, it returns the parameter. refpos :: (Eq a) => ([a],[a]) -> a -> a refpos (a,b) c = let d = pull b $ Cm.pos a c in case d of (Just x) -> x;(Nothing) -> c -- | Test to make sure that all elements in a list are equal to a value. areAll :: (Eq a) => [a] -> a -> Bool areAll x c = not $ Br.imbreak (/=c) x -- | Re-implementation of isPrefixOf for some reason. Tests to see if a list is the first part of antoher list. isBefore :: (Eq a) => [a] -> [a] -> Bool isBefore li tf = take (length tf) li == tf -- | Test to see if a list is surrounded by an item. surrounds :: (Eq a) => (a,a) -> [a] -> Bool surrounds (b,c) a = (head a, last a) == (b,c)