MergeSort w/ Custom Functions
This isn't mergesort! sort' is a different sorting algorithm entirely, so you end up only performing one merge step before kicking it over to (I believe) selection sort.

First let's address the easy stylistic issues so we have a good base to work from. The primary issue is that the argument passed to merge' is a tuple, which is unnecessary, uncurried, and not very Haskell-y. I'll also drop the extra apostrophes where there isn't an actual naming conflict with the Prelude. We use as-patterns to avoid reconstructing patterns we just deconstructed. And let's just toss sort' and filterOne', they're not part of the solution!

mergesort :: (Ord a) =&gt; [a] -&gt; [a]
mergesort []     = []
mergesort xs     = merge (??? left) (??? right)
    where half = (length xs) `div` 2
          left  = take half xs
          right = drop half xs

merge :: (Ord a) =&gt; [a] -&gt; [a] -&gt; [a]
merge [] []                 = []
merge xs []                 = xs
merge [] ys                 = ys
merge xss@(x:xs) yss@(y:ys) = if x &lt;= y then x : merge xs yss else y : merge xss ys
                                 -- ^ Less than *or equal* so our sort is stable


One question is what goes in for the ??? where we used to call sort'? Well, mergesort!

One more complex issue of style is the usage of if in merge. Top-level ifs are better represented as guards in Haskell, it's easier to extend guards and their usage is more idiomatic.

merge xss@(x:xs) yss@(y:ys) | x &lt;= y    = x : merge xs yss
                            | otherwise = y : merge xss ys


One small change we can make is adding another base case to mergesort to account for lists of length 1, which are by definition sorted.

mergesort xs@[x] = xs


There's only one more improvement I'd make to this, and that's to call splitAt rather than take and drop in mergesort. Using both take and drop leads to walking half the list twice in each recursive step where we can walk it only once by doing some more bookkeeping. splitAt takes an index to split a list at, and returns the prefix and remainder just like using take and drop separately would.

So putting all of that together, here's the final version.

mergesort :: (Ord a) =&gt; [a] -&gt; [a]
mergesort []     = []
mergesort xs@[x] = xs
mergesort xs     = merge (mergesort left) (mergesort right)
    where half = (length xs) `div` 2
          (left, right) = splitAt half xs

merge :: (Ord a) =&gt; [a] -&gt; [a] -&gt; [a]
merge [] []                 = []
merge xs []                 = xs
merge [] ys                 = ys
merge xss@(x:xs) yss@(y:ys) | x &lt;= y    = x : merge xs yss
                            | otherwise = y : merge xss ys