Program Tip

"n + k 패턴"이란 무엇이며 Haskell 2010에서 금지 된 이유는 무엇입니까?

programtip 2020. 12. 5. 10:30
반응형

"n + k 패턴"이란 무엇이며 Haskell 2010에서 금지 된 이유는 무엇입니까?


Haskell 2010에 대한 Wikipedia의 항목을 읽을 때 나는 이것을 우연히 발견했습니다.

-- 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 패턴"은 무엇을 의미합니까? 나는 그것이 두 번째 줄이라고 생각하지만 무엇이 잘못되었는지 이해하지 못합니다. 누구든지 거기에 문제가 무엇인지 설명 할 수 있습니까? Haskell 2010에서 이러한 n + k 패턴이 더 이상 허용되지 않는 이유는 무엇입니까?


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두 개의 절이 있는 함수 가 있습니다. 첫 번째 절은 일치 00. 두 번째 절은 값이 5 이상인 Integral 유형의 모든 값과 일치합니다. 바인딩 된 이름 ( 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

You'll notice from the type statements that these are not precisely equal, but the use of a guard is "equal enough". The use of the n-5 in the expression could get tedious and error-prone in any code that uses it in more than one place. The answer would be to use a where clause along the lines of this:

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

The where clause lets you use the calculated expression in multiple places without risk of mistyping. There is still the annoyance of having to edit the border value (5 in this case) in two separate locations in the function definition, but personally I feel this is a small price to pay for the increase in cognitive comprehension.


Further edited to add:

If you prefer let expressions over where clauses, this is an alternative:

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

And that's it. I'm really done now.


The link provided by trinithis is correct; n+k patterns are no longer included in the Haskell spec.

For more background on n+k patterns in general, scroll about 3/5ths of the way down this page on pattern matching, or check out this short post.

참고URL : https://stackoverflow.com/questions/3748592/what-are-nk-patterns-and-why-are-they-banned-from-haskell-2010

반응형