Mẫu n + k là gì? Hãy ngây ngô lúc này:
$ 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
Họ cơ bản là một trường hợp vô cùng đặc biệt đối với mô hình kết hợp mà chỉ làm việc trên con số và đó làm ... tốt, chúng ta hãy chỉ tỏ ra lịch sự và gọi nó là "điều bất ngờ" đối với những số.
Ở đây tôi có chức năng f
có hai mệnh đề. Mệnh đề đầu tiên khớp với 0
và chỉ 0
. Mệnh đề thứ hai khớp với bất kỳ giá trị nào của kiểu Integral có giá trị là 5 hoặc lớn hơn. Tên bị ràng buộc (n
, trong trường hợp này) có giá trị bằng với số bạn đã chuyển trong dấu trừ 5. Vì lý do chúng bị xóa khỏi Haskell 2010, tôi hy vọng bạn có thể thấy lý do ngay bây giờ chỉ với một chút suy nghĩ. (Gợi ý: xem xét các "nguyên tắc tối thiểu ngạc nhiên" và làm thế nào nó có thể hoặc không thể áp dụng ở đây.)
Edited thêm:
Một câu hỏi tự nhiên nảy sinh bây giờ mà các cấu trúc bị cấm là "bạn sử dụng cái gì để thay thế chúng?"
$ 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
Bạn sẽ nhận thấy từ các câu lệnh loại không chính xác như nhau, nhưng việc sử dụng bảo vệ là "đủ". Việc sử dụng các n-5
trong biểu thức có thể nhận được tẻ nhạt và dễ bị lỗi trong bất kỳ mã nào sử dụng nó ở nhiều nơi. Câu trả lời sẽ được sử dụng một điều khoản where
dọc theo dòng này:
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
Mệnh where
phép bạn sử dụng biểu thức tính toán ở nhiều nơi mà không có nguy cơ đánh nhầm. Vẫn còn khó chịu khi phải chỉnh sửa giá trị biên giới (5 trong trường hợp này) ở hai vị trí riêng biệt trong định nghĩa hàm, nhưng cá nhân tôi cảm thấy đây là một mức giá nhỏ để trả cho sự gia tăng hiểu biết về nhận thức.
Tiếp tục chỉnh sửa để thêm:
Nếu bạn thích let
biểu trên where
khoản, đây là một sự thay thế:
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
Và đó là nó. Tôi thực sự đã xong rồi.
cho một gợi ý có lẽ là * lý do * của mẫu n + k kiểm tra bài đăng trên blog tuyệt vời này: http://blog.sigfpe.com/2007/07/data-and-codata.html – jberryman
Đối với những người vẫn còn muốn sử dụng mẫu n + k (tôi đang nhìn bạn, Erik Meijer), có '-XNPlusKPatterns' hoặc' {- # LANGUAGE NPlusKPatterns # -} ' – tlo