{-# LANGUAGE NPlusKPatterns #-}
import Data.Char
pow :: Int -> Int -> Int
pow a 0 = 1
pow a (n + 1) = pow a n * a
myLength :: [a] -> Int
myLength [] = 0
myLength (x:xs) = 1 + myLength xs
myDrop :: Int -> [a] -> [a]
myDrop 0 xs = xs
myDrop (n+1) [] = []
myDrop (n+1) (_:xs) = myDrop n xs
myInit :: [a] -> [a]
myInit [_] = []
myInit (x:xs) = x : init xs
myAnd :: [Bool] -> Bool
myAnd [x] = x
myAnd (x:xs) = x && myAnd xs
myConcat :: [[a]] -> [a]
myConcat [] = []
myConcat (x:xs) = x ++ myConcat xs
myReplicate :: Int -> a -> [a]
myReplicate 0 x = []
myReplicate (n+1) x = x : myReplicate n x
pickUp :: [a] -> Int -> a
pickUp (x:xs) 0 = x
pickUp (x:xs) (n+1) = pickUp xs n
myElem :: Eq a => a -> [a] -> Bool
myElem a [] = False
myElem a (x:xs) = a == x || myElem a xs
merge :: Ord a => [a] -> [a] -> [a]
merge [] xs = xs
merge xs [] = xs
merge (x:xs) (y:ys) = if x <= y then x : merge xs (y:ys) else y : merge (x:xs) ys
halve :: [a] -> ([a], [a])
halve xs = splitAt (length xs `div` 2) xs
msort :: Ord a => [a] -> [a]
msort [] = []
msort [x] = [x]
msort xs = merge (msort ys) (msort zs)
where (ys, zs) = halve xs
mySum :: Num a => [a] -> a
mySum [] = 0
mySum (n:ns) = n + mySum ns
myTake :: Int -> [a] -> [a]
myTake 0 _ = []
myTake (n + 1) [] = []
myTake (n + 1) (x : xs) = x : myTake n xs
myLast :: [a] -> a
myLast [x] = x
myLast (x:xs) = myLast xs