module Slides5 where import Prelude hiding ((.), id, any, all, curry, uncurry, elem) import Slides4 (qsortBy) twice :: (a-> a)-> (a-> a) twice f x = f (f x) iter :: Int-> (a-> a)-> a-> a iter 0 f x = x iter n f x | n > 0 = f (iter (n-1) f x) | otherwise = x (.) :: (b-> c) -> (a-> b)-> a-> c (f . g) x = f (g x) (>.>) :: (a-> b)-> (b-> c)-> a-> c (f >.> g) x = g (f x) id :: a-> a id x = x ins x xs = lessx ++ [x] ++ grteqx where (lessx, grteqx) = span less xs less z = z < x ins' x xs = lessx ++ [x] ++ grteqx where (lessx, grteqx) = span (\z-> z < x) xs sieve :: [Integer]-> [Integer] sieve [] = [] sieve (p:ps) = p:(sieve (filter (\n-> n `mod` p /= 0) ps)) primes :: Integer-> [Integer] primes n = sieve [2..n] all, any :: (a-> Bool)-> [a]-> Bool any p = or . map p all p = and . map p double :: String-> String double = concat . map (replicate 2) curry :: ((a, b)-> c)-> a-> b-> c curry f a b = f (a, b) uncurry :: (a-> b-> c)-> (a, b)-> c uncurry f (a, b) = f a b type Doc = String type Word= String makeIndex :: Doc-> [([Int], Word)] type Line = String makeIndex = lines >.> -- Doc -> [Line] numLines >.> -- -> [(Int,Line)] allNumWords >.> -- -> [(Int,Word)] sortLs >.> -- -> [(Int,Word)] makeLists >.> -- -> [([Int],Word)] amalgamate >.> -- -> [([Int],Word)] shorten -- -> [([Int],Word)] numLines :: [Line]-> [(Int, Line)] numLines lines = zip [1.. length lines] lines splitWords :: Line-> [Word] splitWords = words . map (\c-> if isPunct c then ' ' else c) where isPunct :: Char-> Bool isPunct c = c `elem` ";:.,\'\"!?(){}-\\[]" allNumWords :: [(Int, Line)]-> [(Int, Word)] allNumWords = concat . map oneLine where oneLine :: (Int, Line)-> [(Int, Word)] oneLine (num, line) = map (\w-> (num, w)) (splitWords line) ordWord :: (Int, Word)-> (Int, Word)-> Bool ordWord (n1, w1) (n2, w2) = w1 < w2 || (w1 == w2 && n1 <= n2) sortLs :: [(Int, Word)]-> [(Int, Word)] sortLs = qsortBy ordWord makeLists :: [(Int, Word)]-> [([Int], Word)] makeLists = map (\ (l, w)-> ([l], w)) amalgamate :: [([Int], Word)]-> [([Int],Word)] amalgamate [] = [] amalgamate [p] = [p] amalgamate ((l1, w1):(l2, w2):rest) | w1 == w2 = amalgamate ((l1++ l2, w1):rest) | otherwise = (l1, w1):amalgamate ((l2, w2):rest) shorten :: [([Int],Word)] -> [([Int],Word)] shorten = filter (\ (_, wd)-> length wd >= 4) elem :: Eq a=> a-> [a]-> Bool elem c = any (c ==)