Думайте о совпадении как об упрощенной цепочке if / else. Например:
match "foo" with
| "foo" -> true
| _ -> false
Может быть:
if "foo" = "foo" then true
else false
Активные шаблоны - это неявные вызовы функций. В вашем примере:
match "foo" with
| UpperCase "FOO" -> true
| _ -> false
По существу:
if (UpperCase "foo") = "FOO" then true
else false
Вы соответствуете результату нажатия "foo" в вызове, вам просто не нужно указывать его с обычным синтаксисом вызова функции.
Чтобы ответить на другой вопрос, в данном конкретном случае вы вполне могли бы сделать это для того же эффекта:
let UpperCase (x:string) = x.ToUpper()
match UpperCase "foo" with
| "FOO" -> true
| _ -> false
Это становится немного труднее сделать, когда вы можете получить несколько результатов паттернов, с которыми вы хотите сравнить, и именно здесь активные паттерны более полезны.
Например:
let (|IsInt|IsString|) (x:obj) = match x with :? int -> IsInt | _ -> IsString
match someValue with
| IsInt -> true
| IsString -> false