Práce se seznamy (pokračování)
-- skytí knihovních funkcí které napíšeme
import Prelude hiding
(unzip, zipWith, splitAt, elem, break)
-- ilustrace použití let a where
cislo k =
let cisla = 1 : merge3 (map (2*) cisla) (map (3*) cisla) (map (5*) cisla)
in cisla !! k
cislo' k = cisla !! k where
cisla = 1 : merge3 (map (2*) cisla) (map (3*) cisla) (map (5*) cisla)
-- | sleje tři neklesající posloupnosti a maže duplikáty
merge3 (a:as) (b:bs) (c:cs)
| a<b && a<c = a : merge3 as (b:bs) (c:cs)
| b<a && b<c = b : merge3 (a:as) bs (c:cs)
| c<a && c<b = c : merge3 (a:as) (b:bs) cs
| a==b || a==c = merge3 as (b:bs) (c:cs)
| b==c = merge3 (a:as) bs (c:cs)
unzip :: [(a, b)] -> ([a], [b])
unzip [] = ([],[])
unzip ((x,y):z) = (x:a, y:b) where (a,b) = unzip z
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith _ [] _ = []
zipWith _ _ [] = []
zipWith f (x:xs) (y:ys) = (f x y) : zipWith f xs ys
zvětšuj = zipWith (+) [1..]
splitAt :: Int -> [a] -> ([a], [a])
splitAt 0 xs = ([], xs)
splitAt _ [] = ([], [])
splitAt p (x:xs) = if p>0 then let (ys,zs) = splitAt (p-1) xs in (x:ys, zs)
else error "Negative index"
elem :: Eq a => a -> [a] -> Bool
elem a [] = False
elem a (x:xs) = a == x || elem a xs
-- rozdělení seznamu na pozici kde poprvé uspěje predikát
break :: (a -> Bool) -> [a] -> ([a], [a])
break _ [] = ([], [])
break f (a:as)
| f a = ([], (a:as))
| otherwise = let (b,c) = break f as in (a:b, c)
-- funkce níže nejsou z Prelude ale z Data.List
-- funkce s trochu zvláštním významem, asi nejlépe vysvětlena kódem
union :: Eq a => [a] -> [a] -> [a]
union uPS hOPS
= uPS ++ filter (not . (`elem` uPS)) hOPS
-- = uPS ++ filter (\x -> not (x `elem` uPS)) hOPS
-- rozdělení prvků podle toho zda splňují predikát
partition :: (a -> Bool) -> [a] -> ([a], [a])
partition _ [] = ([], [])
partition f (h:t) = if f h then (h:(fst list), (snd list))
else ((fst list), h:(snd list))
where list = partition f t
findIndices :: (a -> Bool) -> [a] -> [Int]
findIndices = findIndices' 0
findIndices' _ _ [] = []
findIndices' a f (h:t) = (if f h then [a] else []) ++ findIndices' (a+1) f t