Подтвердить что ты не робот

Неоднозначность в синтаксисе сопоставления шаблонов

Сегодня я столкнулся с странностью синтаксиса соответствия шаблону F #, что может привести к явным сбоям в проверке полноты.

type Thing =
    | This
    | That
    | Other

let useThing =
    function
    | This -> "A"
    | That -> "A"
    | That -> "B" // compiler complains
    | Other -> "B"

В приведенном выше сценарии компилятор помогает мне, что второе Это правило никогда не будет согласовано. Однако, если бы я попытался сделать код немного более компактным и написал

let useThing =
    function
    | This | That -> "A"
    | That | Other -> "B"    

Я не получаю никакой помощи от компилятора. Я думаю, причина в том, что | This | That ->. "A" не является ярлыком для | This -> "A" | That -> "A", хотя он очень похож на него (и я видел много примеров кода, которые рассматривают его как таковые). Вместо этого, из того, что я могу найти, символ трубы используется как для разделения отдельных паттернов, так и для шаблона OR.

Это не большая проблема для большинства DU, но я столкнулся с проблемой при сопоставлении DU с большим количеством случаев в другой DU с небольшим количеством случаев. Моя попытка использовать синтаксис ярлыка вызвала ошибку.

Итак, мои вопросы:

  • Является ли моя интерпретация правильной?
  • Есть ли какое-либо обходное решение, кроме перечисления каждого шаблона на отдельной строке?
4b9b3361

Ответ 1

Ваша интерпретация верна.

Если вы не выполняете действия для первого This и второго That, вы создаете шаблон OR, как описано в Match Matching (F #)

Мне это тоже немного запутанно, так как логическое "или" есть || в F #. И хотя легко видеть первый бар как new alternative и второй бар как or в вашем форматировании, он становится менее очевидным в

let useThing =
    function
    | This
    | That -> "A"
    | That
    | Other -> "B"

Однако компилятор может определить, является ли весь шаблон бесполезным, но он не может упростить шаблон. That | Other имеет действительное совпадение и поэтому не является избыточным, как рассмотрено компилятором.
Вы можете думать о гораздо более задействованных шаблонах, где было бы совершенно неясно, можно ли оставить части или упростить их.