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

Охранять десурагирование

Я часто слышу фразу, охранники - это просто синтаксический сахар для if-then-else (или case case).

Может ли кто-нибудь попробовать desugar следующий пример:

halfOf :: Int -> Int
halfOf x | even x = div x 2

(функция преднамеренно частичная)

Спасибо,

4b9b3361

Ответ 1

Семантика сопоставления шаблонов определяется в следующем разделе стандарта: Формальная семантика соответствия шаблонов.

Шаг, относящийся к вашему вопросу, - c. Как вы можете видеть, шаблон совпадает с защитой формы

case v of { p | g1 -> e1 ; ...
              | gn -> en where { decls }
            _     -> e' }

Переводится в шаблонные совпадения без охранников как:

case e' of
{y ->
   case v of {
       p -> let { decls } in
            if g1 then e1 ... else if gn then en else y ;
        _ -> y }}

Таким образом, защита шаблонов определяется в терминах if, а "fallthrough" реализуется путем привязки выражения к переменной, а затем повторения его один раз в предложении else if, а затем в шаблоне, который вы 'd проваливается.

Если нет случая, чтобы пройти до (как в вашем примере), то будет вставлен шаг b, который вставляет случай по умолчанию _ -> error "No match"

Ответ 2

halfOf x =
  if even x
  then div x 2
  else error "Incomplete pattern match" 

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

изменить. Если существует несколько защитных элементов и/или шаблонов, каждое соответствие стража или шаблона переходит в несоответствующую часть предыдущего случая.

compare x y
  | x == y = foo
  | x /= y = bar
compare _ _ = baz

производит

compare x y =
  if x == y
  then foo
  else if x /= y
       then bar
       else baz