2010-10-20 46 views
9

xem xét như sau (Haskell) mã:Đây có phải là hàm chuỗi Fibonacci đệ quy không?

fib=0:1:zipWith (+) fib (tail fib) 

Một đồng nghiệp đang cố gắng để khẳng định rằng đây không phải là một hàm đệ quy vì fib chỉ đơn giản là một danh sách định nghĩa riêng của mình với chính nó và đó là bằng cách nào đó khác với một hàm làm như vậy. Tôi nghĩ anh ấy đang hút thuốc.

Bạn nghĩ sao?

+6

printf "Ồ không, một hàm có đối số bằng 0, chúng tôi không thể có điều đó!" hay là chết; –

+2

Một 'fib' thực sự. – Ani

+1

'zipWith' là hàm đệ quy, và' fib' là kết quả của nó. Không có gì huyền diệu hay không đệ quy về nó. (Các câu trả lời dưới đây cho rằng có "không có chức năng" là nhầm lẫn như đồng nghiệp của bạn.) –

Trả lời

14

Định nghĩa fibonacci với zipWith không phải là hàm đệ quy, trên thực tế không có hàm liên quan, fib là danh sách (dữ liệu) được tự định nghĩa, sử dụng ngữ nghĩa lười của Haskell. Theo nghĩa nào đó, bạn có thể gọi nó là danh sách đệ quy hoặc dữ liệu đệ quy; nhưng không phải chức năng đệ quy. Bạn có thể khó khăn để quấn đầu quanh danh sách đệ quy vì rất ít ngôn ngữ lập trình có bất kỳ thứ gì gần gũi, nhưng bạn sẽ nhận thấy rằng trong Haskell, tất cả các hàm đều lấy chính xác một tham số. fib không nhận bất kỳ tham số nào vì nó không phải là một hàm. Vì không có hàm liên quan, bạn không thể có hàm đệ quy.

Đồng nghiệp của bạn không hút thuốc, anh ấy đã chứng ngộ (hoặc hút thuốc lá, nếu đó là định nghĩa của bạn về chứng ngộ).

+0

Điều này đơn giản là sai: 'zipWith' là một hàm đệ quy xác định chuỗi.'fib' không phải là một danh sách đệ quy: nó là một danh sách đơn giản, không đệ quy đề cập đến kết quả * của việc đánh giá hàm đệ quy' zipWith' *. (Có, Haskell cũng hỗ trợ dữ liệu đệ quy, nhưng điều này đề cập đến các định nghĩa như 'xs = 1: 2: 3: xs', không cho ví dụ của câu hỏi.) –

+2

@Piet Delport:' fib' xuất hiện ở phía bên tay phải của nó định nghĩa .... từ nào bạn sử dụng cho điều đó? Tôi gọi đó là "đệ quy". Không có tính đệ quy hay chức năng (chức năng?) Của 'zipWith' đang được gọi vào câu hỏi ở đây. –

+2

pelotom: Trong Haskell, có sự khác biệt cơ bản giữa dữ liệu * đệ quy * và đệ quy * *. Dữ liệu đệ quy là khi một cấu trúc dữ liệu cụ thể đề cập đến các nhà xây dựng riêng của nó, như xảy ra khi bạn nói 'xs = 1: 2: 3: xs': khuyết điểm cuối cùng tham chiếu trở lại giá trị ban đầu, tạo thành chu trình. Có rất nhiều cách khác nhau để đạt được kiểu đệ quy dữ liệu này: xem [Lấy nút thắt] (http://www.haskell.org/haskellwiki/Tying_the_Knot). Ngược lại, các hàm đệ quy giống như 'zipWith'. Họ có thể hoặc không thể xác định cấu trúc dữ liệu đệ quy, nhưng trong trường hợp này, 'fib' thì không. –

2

Anh ấy đang bẻ khóa - chức năng trên rõ ràng là đệ quy.

+10

Ở trên là rõ ràng đệ quy, nhưng nó không phải là một chức năng. – sepp2k

+0

sepp2k: 'zipWith' là một hàm. –

+1

@Piet: Câu hỏi đặt ra là liệu 'fib' là một hàm đệ quy, không phải là liệu' zipWith' là. – sepp2k

3

Ví dụ bạn đã đưa ra là đệ quy. Nhưng chuỗi Fibonacci của tự nhiên không nhất thiết phải như vậy. Có iterative versions of the algorithm và thậm chí explicit functions.

+3

Lặp lại chỉ là trường hợp đặc biệt của đệ quy, và tạo ra một chuỗi sẽ luôn luôn được đệ quy theo một nghĩa nào đó, vì những lý do rõ ràng hy vọng. Tuy nhiên, công thức tính toán các thuật ngữ đơn độc lập không phải là đệ quy (mặc dù nó sử dụng các hàm có thể được tính toán đệ quy). –

2

Ngoài việc thực hiện Haskell ở đây, các số Fibonacci là một chuỗi được xác định bởi một mối quan hệ lặp lại. Về mặt toán học, mỗi thuật ngữ được định nghĩa là một hàm của các điều khoản trước đó. Đánh bại anh ta bằng ngữ nghĩa toán học.

+0

Mặc dù định nghĩa chuẩn là quan hệ lặp lại, bất kỳ triển khai cụ thể nào cũng có thể sử dụng biểu mẫu đã đóng (mặc dù điều này không có), vì vậy đây không phải là một đối số âm thanh cho các câu hỏi thực hiện. –

9

Đó là đệ quy. Bạn có thể biết vì tên trên LHS của = cũng xuất hiện trên RHS.

Tuy nhiên, không một chức năng. Bạn có thể biết vì loại fib không chứa ->.

+0

Đã lâu rồi tôi mới sử dụng Haskell. Có sử dụng hàm tạo hàm một yêu cầu khó để tạo một hàm không? Tôi không thể tìm thấy câu lệnh xác định trong báo cáo Haskell nhưng loại hàm được định nghĩa từ vựng là 'type :: = btype [-> type]', tức là hàm tạo hàm được theo sau bởi một kiểu khác là tùy chọn. Tuy nhiên, sau đó nó nói rằng "Một loại hàm có dạng' t1 -> t2' ... ". [[source] (http://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-620004)] –

+0

'fib' không phải là hàm,' zipWith' là. –

+1

@Piet: Nhưng đó không phải là câu hỏi. OP đặc biệt nói "hàm chuỗi Fibonacci" này, vì vậy rõ ràng anh ta không hỏi về zipWith (trừ khi bạn đang nói zipWith là "hàm chuỗi Fibonacci"). – sepp2k

2

Vì đây là hàm đệ quy, cần phải có cả đệ quy và hàm. Như sepp2k chỉ ra, nó rõ ràng đệ quy vì tên fib xuất hiện trên cả hai mặt của =. Tức là, fib được định nghĩa theo chính nó.

Đây có phải là chức năng không? Không theo loại của nó. Trong haskell, chúng ta gọi hàm 0-argument là "data". Vì vậy, định nghĩa này của fib tạo ra một cấu trúc dữ liệu đệ quy, nhưng không phải là một hàm đệ quy.

+0

'fib' là một * không * một cấu trúc dữ liệu đệ quy trong trường hợp này:" cấu trúc dữ liệu đệ quy "có nghĩa là một cái gì đó hoàn toàn khác trong Haskell. 'fib' là một cấu trúc dữ liệu vô hạn, không lặp lại (và do đó không đệ quy) được tạo ra bởi một hàm đệ quy (' zipWith'). –

11

Của tôi, tổ ong của những phân biệt thuật ngữ tinh tế. Cái gì thế này"?

fib=0:1:zipWith (+) fib (tail fib) 

Đây không phải là hàm đệ quy. Nó không phải là dữ liệu đệ quy. Nó là một định nghĩa đệ quy.

Điều gì đang được xác định?

fib 

Loại điều gì là fib, theo định nghĩa này?

[Integer] 

Danh sách số nguyên (hoặc có thể là danh sách bất kỳ công cụ số cũ nào).

Có phải là fib một hàm không? Không, đó là một danh sách. fib được xác định đệ quy? Vâng. fib có được xác định đệ quy nếu chúng tôi thay thế zipWith bằng một chức năng không phản hồi cùng loại (ví dụ: \ f xs ys -> xs)? Có, mặc dù nó sẽ là một danh sách được xác định đệ quy khác nhau.

Có phải là fib danh sách vòng tuần hoàn không? Không. "Cấu trúc dữ liệu đệ quy" có nghĩa là "cấu trúc dữ liệu tuần hoàn" không? Không theo giấy của Hoare, "Cấu trúc dữ liệu đệ quy": http://portal.acm.org/book_gateway.cfm?id=63445&type=pdf&bookpath=%2F70000%2F63445%2Fcb-p217-hoare.pdf&coll=&dl=&CFID=15151515&CFTOKEN=6184618

Trong cài đặt đã nhập, "cấu trúc dữ liệu đệ quy" nghĩa là không nhiều hoặc ít hơn "cư dân của loại được xác định đệ quy". Tương ứng "fred" là cấu trúc dữ liệu đệ quy, mặc dù nó không được xác định đệ quy, và thực sự nó có thể bị tác động bởi các hàm đệ quy như ++.

Cụm từ "hàm đệ quy" có nghĩa là "hàm được xác định đệ quy". Cụm từ "giá trị đệ quy" có nghĩa là "giá trị được xác định đệ quy", chẳng hạn như tồn tại trong các ngôn ngữ không nghiêm ngặt: các ngôn ngữ nghiêm ngặt có vấn đề "đệ quy giá trị".

Và nếu bạn nghĩ rằng đó là gàn dở, cố gắng xác định fib như vậy trong một tổng ngôn ngữ lập trình, và bạn sẽ khám phá ra rằng khái niệm "định nghĩa đệ quy" tách ra thành "định nghĩa bởi đệ quy cơ cấu" (tiêu thụ dữ liệu trong một cách dừng lại) và "định nghĩa bởi corecursion bảo vệ" (sản xuất dữ liệu theo cách mà đi), và rằng fib là của giống thứ hai. Trong cài đặt đó, năng suất của fib phụ thuộc rất lớn vào sự lười biếng của zipWith. Trong thiết lập Haskell, tất nhiên, bạn không cần phải lo lắng về bất kỳ công cụ nào để tìm ra loại định nghĩa gì đó, chỉ để tìm hiểu xem nó có một nửa cơ hội thực sự làm việc hay không.

3

Bởi vì hầu hết câu trả lời hỗ trợ đồng nghiệp của bạn liên quan đến các chức năng phần với: "fibkhông một hàm đệ quy" Tôi muốn nói chi tiết về phần đệ quy Conor McBride đã gợi ý trong câu trả lời của anh ta.

Định nghĩa đưa ra cho fibkhông đệ quy, nó là đồng đệ quy.

Co-đệ quy trông rất giống như đệ quy trong đó, như nhiều áp phích đã chỉ ra, LHS của định nghĩa xuất hiện trên RHS quá. Nhưng không có trường hợp cơ bản. Đệ quy và corecursion "chạy theo hướng ngược lại".

Định nghĩa trên của fib bắt đầu từ giá trị ban đầu 0 và 1 và di chuyển "lên" từ đó và tiếp tục. Mặt khác một định nghĩa đệ quy của, nói (một chức năng tính toán) số Fibonacci n-thứ

fib' 0 = 0 
fib' 1 = 1 
fib' n = fib' (n-1) + fib' (n-2) 

đi "xuống" từ số n-thứ cho đến khi nó đạt đến các trường hợp cơ sở và có dừng lại.

Tôi đoán đây vindicates các crackhead ở cả hai điểm :-)


Để đọc thêm kiểm tra bài viết trên wikipedia Corecursion và các liên kết đó. Nếu bạn có thể bắt tay vào nó, Chương 10 của Đường Haskell tới Logic, Toán học và Lập trình bởi Kees Doets và Jan van Eijck có thể đáng xem.

-1

Mặc dù nhiều người trong nhận xét đang tranh cãi liệu định nghĩa có phải là một hàm hay không, nhưng mọi người dường như đồng ý rằng nó là đệ quy.

Đối với đối số chức năng/không có chức năng, trong Haskell, từ quan điểm của lập trình viên, CNTT KHÔNG CÓ VẤN ĐỀ! Bởi vì cả hai hàm và cấu trúc dữ liệu được đánh giá một cách lười biếng, một giá trị và một hàm không có đối số trả về một giá trị là không thể phân biệt được. Những gì bạn có là một danh sách các số nguyên, được đánh giá uể oải và đệ quy. fib đồng thời là "danh sách số nguyên", "hàm không có đối số trả về danh sách số nguyên", "danh sách hàm không có đối số trả về số nguyên" và "hàm không có đối số trả về danh sách hàm không có đối số trở về số nguyên ".

Nó thực sự không thành vấn đề. Ngôn ngữ không phân biệt giữa bốn. Loại lý thuyết không phân biệt giữa bốn (và vô số người khác: một hàm không có đối số trả về bất kỳ đối số nào có giá trị như nhau, như là một hàm không có đối số trả về, vô hạn quảng cáo). Nó thực sự làm cho không có sự khác biệt hay không bạn gọi fib một "chức năng" hay không.

Nhưng đó là đệ quy.

Các vấn đề liên quan