Plan 9 from Bell Labs’s /usr/web/sources/contrib/fernan/nhc98/tests/nofib/real/HMMS/Lists.lhs

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.




        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  %%%%%%%%%%

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].