# map* for Data.List

Henning Thielemann lemming at henning-thielemann.de
Mon Nov 6 06:06:56 EST 2006

```On Sat, 4 Nov 2006, Bulat Ziganshin wrote:

> Hello libraries,
>
> similar to mapFst and Co, we can define:
>
> -- |Map various parts of list
> mapHead f []      =  []
> mapHead f (x:xs)  =  f x : xs
>
> mapTail f []      =  []
> mapTail f (x:xs)  =  x : map f xs
>
> mapInit f []      =  []
> mapInit f xs      =  map f (init xs) : last xs
>
> mapLast f []      =  []
> mapLast f xs      =  init xs : map f (last xs)
>
>
> btw, two last operations may be a bit slow. it's possible to define
> initLast function that returns both parts and still lazy?

In order to make such operations more efficient I defined:

{- | It holds @splitLast xs == (init xs, last xs)@,
but 'splitLast' is more efficient
if the last element is accessed after the initial ones,
because it avoids memoizing list.
-}
splitLast :: [a] -> ([a], a)
splitLast [] = error "splitLast: empty list"
splitLast [x] = ([], x)
splitLast (x:xs) =
let (xs', lastx) = splitLast xs in (x:xs', lastx)

propSplitLast :: Eq a => [a] -> Bool
propSplitLast xs =
splitLast xs  ==  (init xs, last xs)
```