関数型言語のパターンマッチはifやswitch/case文の代わりではあるが、仕組み的にはオーバーロードに近い気がする

変な事を書いてすみません。

タイトルからして訳が分からないと思うのですが、私が最近思っている、パターンマッチに関する考察です。

単純に、よくパターンマッチはifやswitch/case文を書かなくて済む。と言う話があるのですが、使っていくうちに、パターンマッチは単純なifやswitch/case文の置き換えでは無いと思う時があるのです。

例えば、mergesortを自作すると、以下のようになるのですが、ifやswitch/caseで同じように再帰で書こうとすると、結構ごちゃごちゃすると思います。
(まあ、その辺はオブジェクト指向的な別のやり方があると思いますが)

mergesort [] = []
mergesort [z] = [z]
mergesort zs = merge (mergesort xs) (mergesort ys)
	where
		(xs,ys) = mysplitAt (mylength zs `div` 2) zs


merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) | x < y = x:merge xs (y:ys)
merge (x:xs) (y:ys) = y:merge (x:xs) ys

mytake 0 _ = []
mytake _ [] = []
mytake n (x:xs) = x:mytake (n - 1) xs

mydrop 0 xs = xs
mydrop _ [] = []
mydrop n (_:xs) = mydrop (n - 1) xs

mysplitAt n xs = (mytake n xs, mydrop n xs)

mylength = mylength' 0
	where
		mylength' v [] = v
		mylength' v (_:xs) = mylength' (v + 1) xs

オブジェクト指向オーバーロードと全く使い道が違うのは承知なのですが、こう、同じ関数名がズラズラ並ぶと、オーバーロードを引数の数だけじゃなく、値でも同名の違う関数(メソッド)を呼べるようにしたのがパターンマッチなんじゃないか?と、思ってしまう時があります。

まあ、パターンマッチは、あくまで「同じ型の違う値」で機能するので(そして、引数の数は同じじゃないといけないので)、本当に、概念的には全く違うんですけど・・・

仕組み的には、ifやswitch/case文よりも、近いものを何故かオーバーロードに感じてしまう私です。

そう言えば、LLだと型が無いからなのか、オーバーロード使った事ないですね・・・。
そもそも、コンパイラばかり使ってたので、LLの経験自体が少ないですが。