numeric-prelude-0.4.3: src/NumericPrelude/List.hs
module NumericPrelude.List where
import Data.List.HT (switchL, switchR, )
{- * Zip lists -}
{- | zip two lists using an arbitrary function, the shorter list is padded -}
{-# INLINE zipWithPad #-}
zipWithPad :: a {-^ padding value -}
-> (a -> a -> b) {-^ function applied to corresponding elements of the lists -}
-> [a]
-> [a]
-> [b]
zipWithPad z f =
let aux l [] = map (\x -> f x z) l
aux [] l = map (\y -> f z y) l
aux (x:xs) (y:ys) = f x y : aux xs ys
in aux
{-# INLINE zipWithOverlap #-}
zipWithOverlap :: (a -> c) -> (b -> c) -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithOverlap fa fb fab =
let aux (x:xs) (y:ys) = fab x y : aux xs ys
aux xs [] = map fa xs
aux [] ys = map fb ys
in aux
{-
This is exported as Checked.zipWith.
We need to define it here in order to prevent an import cycle.
-}
zipWithChecked
:: (a -> b -> c) {-^ function applied to corresponding elements of the lists -}
-> [a]
-> [b]
-> [c]
zipWithChecked f =
let aux (x:xs) (y:ys) = f x y : aux xs ys
aux [] [] = []
aux _ _ = error "Checked.zipWith: lists must have the same length"
in aux
{- |
Apply a function to the last element of a list.
If the list is empty, nothing changes.
-}
{-# INLINE mapLast #-}
mapLast :: (a -> a) -> [a] -> [a]
mapLast f =
switchL []
(\x xs ->
uncurry (:) $
foldr (\x1 k x0 -> (x0, uncurry (:) (k x1)))
(\x0 -> (f x0, [])) xs x)
mapLast' :: (a -> a) -> [a] -> [a]
mapLast' f =
let recourse [] = [] -- behaviour as needed in powerBasis
-- otherwise: error "mapLast: empty list"
recourse (x:xs) =
uncurry (:) $
if null xs
then (f x, [])
else (x, recourse xs)
in recourse
mapLast'' :: (a -> a) -> [a] -> [a]
mapLast'' f =
switchR [] (\xs x -> xs ++ [f x])