This module provides a number of useful general purpose functions for processing lists that are not provided in the Haskell Standard Prelude. \begin{haskell}{Lists} > module Lists( blocks, interleave, interleaveRight, > mapfst, mapsnd, mapAccumlfst, > foldr1_2op, > hamming > ) where > import List(genericSplitAt)--1.3 \end{haskell} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section*{blocks} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The function \verb~blocks~ breaks a list into a list of non-overlapping fixed-length sublists (``blocks''), except that the last block may be shorter than the requested block-size. Note that \verb~blocks 0~ applied to a non-empty list returns an infinite list of empty lists. \begin{haskell}{blocks} > blocks :: (Integral b) => b -> [a] -> [[a]] > blocks n [] = [] > blocks n xs = block : blocks n rest > where > (block, rest) = genericSplitAt n xs \end{haskell} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section*{interleave, interleaveRight} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{haskell}{interleave} > interleave a xs = a : interleaveRight a xs \end{haskell} \fixhaskellspacing\begin{haskell}{interleaveRight} > interleaveRight a (x:xs) = x : a : interleaveRight a xs > interleaveRight a [] = [] \end{haskell} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section*{mapfst, mapsnd} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% It will be useful to be able to apply a function pointwise to the first components in a list of pairs, leaving the second components untouched. The function \verb~mapfst~ provides this capability. \begin{haskell}{mapfst} > mapfst :: (a -> c) -> [(a, b)] -> [(c, b)] > mapfst _ [] = [] > mapfst f ((a,b):rps) = (f a, b) : mapfst f rps \end{haskell} The function \verb~mapsnd~ applies a function to the second components in a list of pairs, leaving the first components untouched: \begin{haskell}{mapsnd} > mapsnd :: (b -> c) -> [(a, b)] -> [(a, c)] > mapsnd _ [] = [] > mapsnd f ((a,b):rps) = (a, f b) : mapsnd f rps \end{haskell} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section*{mapAccumlfst} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% This function is a modified version of the function \verb~mapAccuml~ provided with \verb~hbc~ in the library module \verb~ListUtil~. This version transforms only the first coordinates of a list of pairs, leaving the second coordinates untouched. \begin{haskell}{mapAccumlfst} > mapAccumlfst :: (s -> a -> (s,b)) -> > s -> > [(a,c)] -> > (s, [(b,c)]) > mapAccumlfst f s [] = (s, []) > mapAccumlfst f s ((x,d):rps) = (s'', (y,d):rys) > where > (s', y) = f s x > (s'', rys) = mapAccumlfst f s' rps \end{haskell} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section*{foldr1\_2op} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% This is a variant of the Standard Prelude function \verb~foldr1~ that takes two operators. \begin{haskell}{foldr1_2op} > foldr1_2op op1 _ [x,y] = x `op1` y > foldr1_2op op1 op2 (x:y:rxs) = (x `op1` y) `op2` foldr1_2op op1 op2 rxs > foldr1_2op _ _ [] = error "foldr1_2op []" \end{haskell} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section*{hamming} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The function \verb~hamming~ counts the number of positions in which two equal-length lists differ. Obviously, generalizations could be defined for lists of different length, but our only application at the moment is for lists of equal length. \begin{haskell}{hamming} > hamming :: (Eq a) => [a] -> [a] -> Int > hamming (x:rxs) (y:rys) > | x == y = hamming rxs rys > | otherwise = 1 + hamming rxs rys > hamming [] [] = 0 > hamming [] (_:_) = error hamming_error > hamming (_:_) [] = error hamming_error > hamming_error = "hamming applied to two lists having different lengths" \end{haskell} %%%%%%%%%% End of Lists.lhs %%%%%%%%%%