packages feed

swish-0.2.1: Swish/HaskellRDF/Sort/ListLib.lhs

%-------------------------------=  --------------------------------------------
\section{List library}
%-------------------------------=  --------------------------------------------

%align

> module Swish.HaskellRDF.Sort.ListLib 
> where

%align 33

> simple			:: [a] -> Bool
> simple []			=  True
> simple [a]			=  True
> simple (a1 : a2 : as)		=  False

> halve				:: [a] -> ([a], [a])
> halve as			=  splitAt (length as `div` 2) as

> repSplit			:: [Int] -> [a] -> [[a]]
> repSplit ns []		=  []
> repSplit [] xs		=  [xs]
> repSplit (n : ns) xs		=  ys : repSplit ns zs
>   where (ys, zs)		=  splitAt n xs

> copy				:: [a] -> [a]
> copy				=  concat . repeat

> interleave			:: [a] -> [a] -> [a]
> interleave [] y		=  y
> interleave (a:x) y		=  a : interleave y x

> uninterleave			:: [a] -> ([a], [a])
> uninterleave []		=  ([], [])
> uninterleave [a]		=  ([a], [])
> uninterleave (a1 : a2 : as)	=  (a1 : odds, a2 : evens)
>     where (odds, evens)	=  uninterleave as

%- - - - - - - - - - - - - - - -=  - - - - - - - - - - - - - - - - - - - - - -
\subsection{folds}
%- - - - - - - - - - - - - - - -=  - - - - - - - - - - - - - - - - - - - - - -

Here is yet another colleague of |foldr| and |foldl|: |foldm|
constructs a balanced expression tree.

> foldm				:: (a -> a -> a) -> a -> [a] -> a
> foldm (*) e []		=  e
> foldm (*) e x			=  fst (rec (length x) x)
>     where rec 1 (a:x)		=  (a, x)
>           rec n x		=  (a * b, z)
>               where m		=  n `div` 2
>                     (a, y)	=  rec (n - m) x 
>                     (b, z)	=  rec m       y

> gfoldm			:: a -> (b -> a) -> (a -> a -> a) -> [b] -> a
> gfoldm e f (*) []		=  e
> gfoldm e f (*) x		=  fst (rec (length x) x)
>     where rec 1 (a:x)		=  (f a, x)
>           rec n x		=  (a * b, z)
>               where m		=  n `div` 2
>                     (a, y)	=  rec (n - m) x 
>                     (b, z)	=  rec m       y

Jon's |treefold|. In a sense |foldm| works top-down and |treefold|
works bottom-up.

> treefold			:: (a -> a -> a) -> a -> [a] -> a
> treefold (*) e []		=  e
> treefold (*) e [a]		=  a
> treefold (*) e (a:b:x)	=  treefold (*) e (a * b : pairfold (*) x)

> pairfold			:: (a -> a -> a) -> [a] -> [a]
> pairfold (*) (a:b:x)		=  a * b : pairfold (*) x
> pairfold (*) x		=  x -- here |x| will have fewer than two 

Note that |foldm| and |treefold| construct different trees: |foldm|
returns a Braun tree while |treefold| returns a tree of the form
\[	
    |t1 * (t2 * (.. (tn-1 * tn) ..))|
\]
where the |ti|'s are complete binary trees in decreasing size. The size
of the trees corresponds to the binary decomposition of the input
length.

"`Inverse"' Funktion zum Preorder-Durchlauf.

> prefold			:: (a -> b -> b -> b) -> b -> [a] -> b
> prefold f e as		=  fst (rec (length as) as)
>     where rec 0 as		=  (e, as)
>           rec (n + 1) []	=  error "rec"
>           rec (n + 1) (a : as)=  (f a l r, as2)
>               where m		=  n `div` 2
>                     (l, as1)	=  rec (n - m) as
>                     (r, as2)	=  rec m       as1

> perms				:: [a] -> [[a]]
> perms []			=  [ [] ]
> perms (a:x)			=  [ z | y <- perms x, z <- insertions a y ]
>
> insertions			:: a -> [a] -> [[a]]
> insertions a []		=  [ [a] ]
> insertions a x@(b:y)		=  (a:x) : [ b:z | z <- insertions a y ]

> spaces			:: Int -> [Char]
> spaces n			=  replicate (max n 0) ' '

> cjustify, ljustify, rjustify	:: Int -> String -> String
> cjustify                      =  cjustifyWith ' '
> ljustify n s			=  s ++ spaces (n - length s)
> rjustify n s			=  spaces (n - length s) ++ s

> indent			:: Int -> String -> String
> indent n s			=  spaces n ++ s

> cjustifyWith			:: a -> Int -> [a] -> [a]
> cjustifyWith c n s            =  replicate l c ++ s ++ replicate r c
>     where m                   =  n - length s
>           l                   =  m `div` 2
>           r                   =  m - l