90 lines
2.5 KiB
Haskell
90 lines
2.5 KiB
Haskell
myAnd :: [Bool] -> Bool
|
|
myAnd [x] = x
|
|
myAnd (x:xs) = x && (myAnd xs)
|
|
|
|
myConcat :: [[a]] -> [a]
|
|
myConcat [xs] = xs
|
|
myConcat (xs:xss) = xs ++ myConcat xss
|
|
|
|
myReplicate :: Int -> a -> [a]
|
|
myReplicate 1 v = v : []
|
|
myReplicate n v = v : myReplicate (n-1) v
|
|
|
|
(*!!) :: [a] -> Int -> a
|
|
(*!!) (x:_) 0 = x
|
|
(*!!) (x:xs) i = (*!!) xs (i-1)
|
|
|
|
myElem :: Eq a => a -> [a] -> Bool
|
|
myElem x [] = False
|
|
myElem x (y:xs) | x == y = True
|
|
| otherwise = myElem x xs
|
|
|
|
iSort :: Ord a => [a] -> [a]
|
|
-- Base cases
|
|
iSort [] = []
|
|
iSort [x] = [x]
|
|
iSort (x:y:[]) | x <= y = [x,y]
|
|
| otherwise = [y,x]
|
|
|
|
-- Split into first and rest of element.
|
|
-- Then, we sort the remaining list recursive.
|
|
-- Finally, we use the correct ordering to recurisvely call iSort for
|
|
-- the rest of the list with y in the correct order.
|
|
iSort (x:xs) | x <= y = x : iSort (y:l)
|
|
| otherwise = y : iSort (x:l)
|
|
where (y:l) = iSort xs
|
|
|
|
-- helper function
|
|
-- Base case.
|
|
mySplit 0 p = p
|
|
-- mySplit will collect from the 2nd ordered pair, and move n
|
|
-- elements into the first list.
|
|
-- This is done recursively by decrementing n on each call, and moving
|
|
-- one y into left of the ordered pair.
|
|
mySplit n (xs,(y:ys)) = mySplit (n-1) (xs++[y], ys)
|
|
|
|
splitHalf :: [a] -> ([a], [a])
|
|
-- splitHalf simply calls mySplit with n = length / 2.
|
|
splitHalf xs = mySplit (div l 2) ([], xs)
|
|
where l = length xs
|
|
|
|
mergeList :: Ord a => [a] -> [a] -> [a]
|
|
-- Base case.
|
|
-- If one of the lists is empty, then we can just return one of the
|
|
-- lists.
|
|
mergeList [] ys = ys
|
|
mergeList xs [] = xs
|
|
|
|
-- Lots of pattern matching.
|
|
-- axs, ays = "All xs"
|
|
-- x,y = Sorting value
|
|
-- ys,xs = "Rest of xs"
|
|
mergeList axs@(x:xs) ays@(y:ys)
|
|
-- If x <= y, x should go first.
|
|
-- Then we can merge the rest of xs with all of ays.
|
|
| x <= y = x : mergeList xs ays
|
|
-- Otherwise, we can just call mergeList again.
|
|
| otherwise = y : mergeList axs ys
|
|
|
|
-- Some helper function
|
|
-- Apply a function that takes 2 params and apply it to an ordered pair
|
|
-- with the 2 parameters.
|
|
applyPair :: (a->b->c) -> (a,b) -> c
|
|
applyPair f (x,y) = f x y
|
|
|
|
-- Apply a function to each part of the pair.
|
|
applyEachPair :: (a->b) -> (a,a) -> (b,b)
|
|
applyEachPair f (x, y) = (f x, f y)
|
|
|
|
mergeSort :: Ord a => [a] -> [a]
|
|
-- Base cases
|
|
mergeSort [] = []
|
|
mergeSort [x] = [x]
|
|
|
|
-- To merge a list xs,
|
|
-- we split the list in half, and recursive apply mergeSort to each
|
|
-- half.
|
|
-- Then, we mergeList on both of them.
|
|
mergeSort xs = applyPair mergeList $ applyEachPair mergeSort $ splitHalf xs
|
|
|