охрана - PullRequest
       31

охрана

12 голосов
/ 15 ноября 2010

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

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

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

Функция намеренно частичная)

Спасибо,

Ответы [ 2 ]

12 голосов
/ 15 ноября 2010
halfOf x =
  if even x
  then div x 2
  else error "Incomplete pattern match" 

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

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

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
3 голосов
/ 15 ноября 2010

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

Шаг, который относится к вашему вопросу - 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и «падение» реализуется путем привязки выражения к переменной и повторения его один раз в предложении else в if, а затем в шаблоне, к которому вы переходите.

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

...