module RSAGL.Math.ListUtils (doubles, loopedDoubles, consecutives, loopedConsecutives, zeroToOne) where import RSAGL.Math.Types import Debug.Trace -- | Transforms a list to a list of adjacent elements. -- -- @doubles [1,2,3,4,5] = [(1,2),(2,3),(3,4),(4,5)]@ doubles :: [a] -> [(a,a)] doubles [] = [] doubles [_] = [] doubles (x:y:zs) = (x,y) : doubles (y:zs) -- | loopedDoubles transforms a list to a list of adjacent elements, looping -- back to the beginning of the list. -- -- @loopedRSdoubles [1,2,3,4,5] = [(1,2),(2,3),(3,4),(4,5),(5,1)]@ loopedDoubles :: [a] -> [(a,a)] loopedDoubles as = loopedDoubles_ (head as) as where loopedDoubles_ _ [] = [] loopedDoubles_ a [x] = [(x,a)] loopedDoubles_ a (x:y:zs) = (x,y) : loopedDoubles_ a (y:zs) -- | Answers a list containing every sequence of n consecutive -- elements in the parameter. -- -- @consecutives 3 [1,2,3,4] = [[1,2,3],[2,3,4]]@ consecutives :: Int -> [a] -> [[a]] consecutives n xs = let taken = take n xs in if (length taken == n) then (taken : (consecutives n $ tail xs)) else [] -- | Answers a list containing every sequence of n consecutive -- elements in the parameter, looping back to the beginning of the list. -- -- @consecutives 3 [1,2,3,4] = [[1,2,3],[2,3,4],[3,4,1],[4,1,2]]@ loopedConsecutives :: Int -> [a] -> [[a]] loopedConsecutives n xs = consecutives n $ take (n + length xs - 1) $ cycle xs -- | Creates a list of numbers from 0.0 to 1.0, using n steps. -- This can't be done with the enum-from-to method, due to roundoff errors. zeroToOne :: Integer -> [RSdouble] zeroToOne n | n > 100000 = trace ("Warning: zeroToOne was asked for " ++ show n ++ " subdivisions, which seems high. Using 100,000 instead.") zeroToOne 100000 zeroToOne n = map (*x) [0..(fromInteger $ n-1)] where x = recip (fromInteger $ n - 1)