Что такое "N+k patterns" и почему они запрещены в Haskell 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 ответов:
что такое 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 1The
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и это все. Я действительно закончила.
Comments