2016-11-28 18 views
14

Vì vậy, tôi là một lập trình viên có kinh nghiệm về OOP (chủ yếu là C++), vừa bắt đầu nhúng các ngón chân của tôi vào với lập trình hàm. Từ sự hiểu biết của tôi, trong một mô hình thuần túy chức năng, các chức năng không nên có điều kiện và nên được chia nhỏ càng nhiều càng tốt bằng cách sử dụng currying. Ai đó có thể cung cấp cho tôi phiên bản chức năng "thuần túy" của ví dụ sau không? Tốt hơn là sử dụng mọi kỹ thuật chặt chẽ sẽ là một phần của mô hình chức năng:Lập trình hoàn toàn chức năng

let rec greatestCommonFactor a b = 
    if a = 0 then b 
    elif a < b then greatestCommonFactor a (b - a) 
    else greatestCommonFactor (a - b) b 
+2

Chào mừng bạn đến Stack Overflow! Và xin chúc mừng vì đã đọc rõ [Trung tâm trợ giúp] (http://stackoverflow.com/help) trước khi đặt câu hỏi: đó là một câu hỏi tuyệt vời đầu tiên. Rõ ràng, ngắn gọn, với chính xác các chi tiết cần thiết và không có một loạt các verbiage không liên quan. Tôi sẽ upvote câu hỏi của bạn 5 lần nếu tôi có thể. Làm tốt! – rmunn

Trả lời

16

Chức năng mẫu mà bạn đã cung cấp đã hoàn toàn hoạt động. Khi chúng ta nói về một hàm thuần khiết, những gì chúng ta đang nói đến là thuộc tính của hàm là referentially transparent.

Một biểu thức là tham chiếu trong suốt nếu nó có thể được thay thế bằng giá trị của nó mà không làm thay đổi ảnh hưởng của chương trình. Để cung cấp một ví dụ đơn giản, hãy tưởng tượng các chức năng:

let add2 x = x + 2 

Bây giờ, bất cứ nơi nào mà giá trị add2 2 xuất hiện trong chương trình của chúng tôi, chúng ta có thể thay thế giá trị 4 mà không thay đổi hành vi của các chương trình.

Hãy tưởng tượng bây giờ mà chúng ta thêm một số hành vi bổ sung vào các chức năng in ra cửa sổ Console:

let add2Print x = 
    printfn "%d" x 
    x + 2 

Mặc dù kết quả của hàm là giống như trước đây, chúng ta không còn có thể thực hiện thay giá trị với giá trị 4 mà không thay đổi hành vi của chương trình của chúng tôi vì chức năng của chúng tôi có tác dụng phụ bổ sung khi in trên bảng điều khiển.

Hàm này không còn tham chiếu trong suốt và do đó không phải là hàm thuần túy.


let rec greatestCommonFactor a b = 
    if a = 0 then b 
    elif a < b then greatestCommonFactor a (b - a) 
    else greatestCommonFactor (a - b) b 

Nhìn vào chức năng này mà bạn đã cung cấp, không có tác dụng phụ có liên quan đến thực hiện của nó. Chúng tôi sẽ luôn nhận được cùng giá trị đầu ra cho các đầu vào đã cho ab, do đó, đây là một hàm thuần túy.

Để rõ ràng, hoàn toàn không có vấn đề gì với các hàm chứa điều kiện trong lập trình hàm. Tuy nhiên, thông thường, chúng tôi sử dụng mẫu phù hợp hơn là các biểu thức if/elif/else nhưng trong ví dụ bạn đã mô tả, đây hoàn toàn là kiểu cách. Biểu thức thay thế của hàm của bạn bằng cách sử dụng đối sánh mẫu sẽ là:

let rec greatestCommonFactor a b = 
    match a with 
    |0 -> b 
    |a' when a' < b -> greatestCommonFactor a' (b - a') 
    |a' -> greatestCommonFactor (a' - b) b 
+2

Vì vậy, các điều kiện không quan trọng? Tôi đã bị ấn tượng rằng việc loại bỏ các điều kiện được ưu tiên trong mô hình chức năng. Chẳng hạn như sử dụng lambdas tại chỗ của họ. – Zach

+4

@Zach Một số ngôn ngữ chức năng có xu hướng hướng tới các kiểu terse, nhưng các điều kiện vẫn tồn tại. Ngay cả Haskell có một từ khóa 'if', mặc dù, giống như trong F #, bạn có xu hướng sử dụng mẫu khớp với nhiều hơn' if' và 'then'. –

+5

@Zach Không, điều kiện hoàn toàn không quan trọng. Thường thì các điều kiện trong lập trình hàm được xử lý thông qua kết hợp mẫu thay vì thông qua các biểu thức 'if/elif/else' nhưng trong trường hợp bạn đã trình bày ở đây, nó hoàn toàn là kiểu cách. – TheInnerLight

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