Какая разница между регистром и матчем? - PullRequest
0 голосов
/ 06 декабря 2018

Меня смущало различие между match и case документе , упоминается, что match поддерживает общее сопоставление с образцом.

> (define (m x)
    (match x
      [(list a b c)
       #:when (= 6 (+ a b c))
       'sum-is-six]
      [(list a b c) 'sum-is-not-six]))
> (m '(1 2 3))
'sum-is-six

> (m '(2 3 4))
'sum-is-not-six 

В этом примере я подумал, что могу переписать его, используя выражение case.Но, кажется, это довольно сложно.Я должен получить длину ввода x и, возможно, лямбда-функцию, чтобы получить сумму элементов x и сравнить ее с 6.

Так что, я думаю, мы предпочитаем match при сопоставлении с образцом.Это правда?Любая разница, кроме этого?

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Есть два отличия:

  1. match намного мощнее, чем casecase нет «шаблонов», как у match, и он неявно цитирует данные в каждом «вопросе ветвления».Он сравнивает только приведенную форму данных со значением, как оператор switch.match имеет другой и гораздо более богатый язык шаблонов.

x в каждом вопросе ветвления этих двух примеров

(case 5
  [(x) 10]
  [else 'fail])
;=> 'fail

(case 'x
  [(x) 10]
  [else 'fail])
;=> 10

неявно цитируется как символ'x.В терминах соответствия это эквивалентно

(match 5
  ['x 10]
  [_ 'fail])
;=> 'fail

(match 'x
  ['x 10]
  [_ 'fail])
;=> 10

Где цитирование является одним из многих вариантов создания шаблонов, а не по умолчанию.Если вы пропустите цитату в match, x больше не будет символом;это подстановочный знак, который соответствует чему-либо и определяет x как результат.

(match 5
  [x (+ x 1)])
;=> 6

Этого никогда не произойдет с case из-за неявного цитирования case.

case вопросы ветвления имеют несколько данных для каждой ветви.

Эти данные должны быть заключены в скобки.

(case expr
  [(datum ...) answer]
  ...)

Где match имеет только один шаблон на ветку (без скобок)

(match expr
  [pattern answer]
  ...)
0 голосов
/ 06 декабря 2018

Вы сказали это сами, match выполняет общее сопоставление с шаблоном (очень мощная концепция!), Тогда как case проверяет только, принадлежит ли значение одному из нескольких списковвозможные (неявно цитируемые) значения.Все, что case делает, это синтаксический сахар для cond с несколькими условиями, например:

(case (+ 7 5)
  [(1 2 3) 'small]
  [(10 11 12) 'big]
  [else 'other])

... примерно эквивалентно:

(let ((val (+ 7 5)))
  (cond ((or (equal? val 1) (equal? val 2) (equal? val 3))
        'small)
        ((or (equal? val 10) (equal? val 11) (equal? val 12))
        'big)
        (else 'other)))

Принимая во внимание match делает некоторые сложные сопоставления;он проверяет, является ли значение одним из нескольких возможных шаблонов , он не только сравнивает значения на равенство, он также проверяет тип и «форму» значения с шаблоном, и мы можем даже добавить дополнительные ограниченияиспользуя #:when.Чтобы понять, насколько это сложно, проверьте в разделе грамматика документации match .

...