Что такое «n + k паттерны» и почему они запрещены в Haskell 2010? - PullRequest
59 голосов
/ 20 сентября 2010

Читая Запись Википедии о Haskell 2010 Я наткнулся на это:

-- using only prefix notation and n+k-patterns (no longer allowed in Haskell 2010)
factorial 0 = 1
factorial (n+1) = (*) (n+1) (factorial n)

Что они подразумевают под "n + k шаблонами"? Я предполагаю, что это вторая строка, но я не понимаю, что может быть не так с этим. Кто-нибудь может объяснить, в чем здесь проблема? Почему эти шаблоны n + k больше не разрешены в Haskell 2010?

Ответы [ 2 ]

63 голосов
/ 20 сентября 2010

Что такое n + k шаблонов?Взгляните на это:

$ ghci
GHCi, version 6.12.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> let f 0 = 0 ; f (n+5) = n
Prelude> :t f
f :: (Integral t) => t -> t
Prelude> f 0
0
Prelude> f 1
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f

Prelude> f 2
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f

Prelude> f 3
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f

Prelude> f 4
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f

Prelude> f 5
0
Prelude> f 6
1

По сути, это чрезвычайно особый случай сопоставления с образцом, который работает только на числа и который ... ну, давайте просто будем вежливы и будем называть это "неожиданными вещами"на эти числа.

Здесь у меня есть функция f, которая имеет два предложения.Первое предложение соответствует 0 и только 0.Второе предложение соответствует любому значению типа Integral, значение которого равно 5 или больше.Связанное имя (в данном случае n) имеет значение, равное числу, которое вы передали в минус 5. Что касается того, почему они были удалены из Haskell 2010, я надеюсь, что теперь вы можете увидеть причину с небольшим количествоммышления.(Подсказка: рассмотрите «принцип наименьшего удивления» и то, как он может или не может применяться здесь.)


Отредактировано, чтобы добавить:

Естественный вопросвозникать сейчас, когда эти конструкции запрещены, - это «что вы используете для их замены?»

$ ghci
GHCi, version 6.12.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> let f 0 = 0 ; f n | n >= 5 = n - 5
Prelude> :t f
f :: (Num t, Ord t) => t -> t
Prelude> f 0
0
Prelude> f 1
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f

Prelude> f 2
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f

Prelude> f 3
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f

Prelude> f 4
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f

Prelude> f 5
0
Prelude> f 6
1

Вы заметите из утверждений типа, что они не совсем равны, но использование охранника"достаточно равный".Использование n-5 в выражении может стать утомительным и подверженным ошибкам в любом коде, который использует его более чем в одном месте.Ответом будет использование предложения where в соответствии с приведенным ниже текстом:

Prelude> let f 0 = 0 ; f n | n >= 5 = n' where n' = n - 5
Prelude> :t f
f :: (Num t, Ord t) => t -> t
Prelude> f 0
0
Prelude> f 5
0
Prelude> f 6
1

Предложение where позволяет использовать вычисленное выражение в нескольких местах без риска опечатки.Все еще раздражает необходимость редактировать значение границы (в данном случае 5) в двух разных местах в определении функции, но лично я считаю, что это небольшая цена за увеличение когнитивного понимания.


Далее отредактировано, чтобы добавить:

Если вы предпочитаете let выражений над where предложениями, это альтернатива:

Prelude> let f 0 = 0 ; f n | n >= 5 = let n' = n - 5 in n'
Prelude> :t f
f :: (Num t, Ord t) => t -> t
Prelude> f 0
0
Prelude> f 5
0

И этоЭто.Я действительно закончил.

4 голосов
/ 20 сентября 2010

Ссылка, предоставленная trinithis, верна; n + k паттерны больше не включены в спецификацию Haskell.

Чтобы узнать больше о n + k шаблонах в целом, прокрутите примерно 3/5 пути вниз по этой странице по шаблонам или ознакомьтесь с этой короткой публикацией .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...