cs420/Week7/lecture.hs

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