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

Совпадение идентичных значений

Я просто задавался вопросом, можно ли несколько раз сопоставлять одни и те же значения с возможностями сопоставления шаблонов языков программирования (Haskell/F #/Caml).

Просто подумайте о следующем примере:

plus a a = 2 * a
plus a b = a + b

Первый вариант будет вызываться, когда функция вызывается с двумя одинаковыми значениями (которые будут сохранены в a).

Более полезным приложением было бы это (упрощение AST).

simplify (Add a a) = Mult 2 a

Но Haskell отклоняет эти коды и предупреждает меня о конфликтующих определениях для a. Я должен делать явные case/if-checks вместо этого, чтобы узнать, получили ли функция одинаковые значения. Есть ли какой-либо трюк, указывающий, что переменная, которую я хочу сопоставить, будет происходить несколько раз?

4b9b3361

Ответ 1

Это называется нелинейным рисунком. Недавно было опубликовано несколько сообщений о списке рассылки haskell-cafe. Вот два:

http://www.mail-archive.com/[email protected]/msg59617.html

http://www.mail-archive.com/[email protected]/msg62491.html

Нижняя строка: это невозможно реализовать, но было принято решение для простоты.

Кстати, вам не нужны if или case, чтобы обойти это; (слегка) более чистый способ заключается в использовании защитного устройства:

a `plus` b
  | a == b = 2*a
  | otherwise = a+b

Ответ 2

У вас не может быть двух параметров с тем же именем, чтобы указать, что они должны быть равными, но вы можете использовать охранники, чтобы отличать случаи, такие как это:

plus a b
  | a == b    = 2 * a
  | otherwise = a + b

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

Ответ 3

Я только что просмотрел темы списка рассылки, заданные в ответе Томаса, и самый первый ответ в одном из них имеет смысл и объясняет, почему такой "шаблон" не имеет большого смысла вообще: что делать, если a является функцией? (В общем случае невозможно проверить, что две функции равны.)

Ответ 4

Haskell не делает унификации.

Ответ 5

Я реализовал новый язык функционального программирования, который может обрабатывать нелинейные шаблоны в Haskell.

https://github.com/egison/egison

На моем языке ваша функция plus написана следующим образом.

(define $plus
  (match-lambda [integer integer]
    {[[$a ,a] (* a 2)]
     [[$a $b] (+ a b)]}))