2013-08-29 23 views
5

Tôi có hai hàm là thành phần của hàm thuần túy. Chức năng đầu tiên phải mất một bưu kiện, xây dựng một ngôi nhà trên đó, và chụp ảnh để quảng cáo nó trong một tạp chí:Làm thế nào để tránh tính toán không cần thiết khi soạn các hàm thuần túy trong một ngôn ngữ chức năng?

let buildAndAdvertiseHouse parcel = 
    parcel 
    |> inspect 
    |> buildWalls 
    |> buildRoof 
    |> takePhoto 
    |> advertise 

Chức năng thứ hai cũng có một bưu kiện, xây dựng một ngôi nhà trên đó, và cho biết thêm một hoàn thiện chạm vào nó:

let buildAndCompleteHouse parcel = 
    parcel 
    |> inspect 
    |> buildWalls 
    |> buildRoof 
    |> paintWalls 
    |> addFurniture 

Rõ ràng là hai hàm cũng thuần túy, vì chúng là một thành phần của hàm thuần túy. Bây giờ tôi có một bưu kiện, giả sử niceParcel và tôi muốn áp dụng cả hai chức năng cho nó. Tuy nhiên, tôi muốn tránh rằng ba hàm đầu tiên được tính hai lần vì chúng mất một thời gian lớn để tính toán và chúng được chia sẻ giữa hai hàm.

Làm cách nào để tôi tái cấu trúc mã của mình, vì vậy các tính toán không cần thiết này có thể tránh được, trong khi vẫn giữ các hàm thuần túy đẹp có ý nghĩa rõ ràng?

+1

Nếu 'bưu kiện' không phải là loại chung, thì bạn có thể làm cho mã thành ngữ hơn với' let buildAnd ... = inspect >> buildWalls >> ... >> quảng cáo' (và có thụt đầu dòng thích hợp) –

+1

Về câu hỏi, tại sao không chia hai chức năng của bạn thành ba hàm có tên 'build',' advertising' và 'completeHouse'? –

+0

Chúng tạo thành một thực thể có thể được sử dụng trong các phần khác nhau của chương trình. Tất nhiên họ có thể được chia, nhưng sau đó thực thể này bị mất. Trong trường hợp đó, nếu bạn muốn sử dụng chúng, bạn sẽ phải biết các hoạt động bên trong, cụ thể là nó được xây dựng đầu tiên và sau đó hoàn thành hoặc được quảng cáo. Tôi muốn tránh rằng bạn phải biết các hoạt động bên trong. – Tuur

Trả lời

5

Như những người khác được đề cập trong các nhận xét, tôi nghĩ cách tiếp cận tốt nhất là biến phần phổ biến thành hàm build. Ngay cả khi bạn không có ý định sử dụng chức năng cho các mục đích khác, đây là một cách sạch sẽ để cấu trúc mã chức năng.

Trong F #, bạn có thể xác định loại đại diện cho một ngôi nhà được xây dựng một phần, nhưng không để lộ bên trong. Điều này có nghĩa rằng người gọi của thư viện của bạn có thể sử dụng build để xây dựng một ngôi nhà được xây dựng một phần, nhưng sau đó điều duy nhất họ có thể làm gì với nó là sử dụng hai chức năng mà bạn cung cấp:

module Houses = 
    type House = private HouseData of <whatever> 
    let build parcel = (...) 

    let buildAndAdvertiseHouse house = 
    house 
    |> takePhoto 
    |> advertise 

    let buildAndCompleteHouse house = 
    house 
    |> paintWalls 
    |> addFurniture 

Bạn có thể giấu một thực tế rằng người ta cần xây dựng một ngôi nhà trước khi bạn có thể quảng cáo & hoàn thành nó theo nhiều cách khác nhau. Ví dụ, nếu bạn thường thực hiện cả hai thao tác, bạn có thể định nghĩa một hàm gọi cả ba hàm - và người dùng thư viện của bạn có thể sử dụng hoặc tìm hiểu thêm về xây dựng nhà và sử dụng ba hàm nếu chúng cần kiểm soát tốt hơn.

Một cách tiếp cận khác là chỉ cần bọc chức năng theo một loại đơn giản. F # hỗn hợp chức năng và hướng đối tượng theo phong cách, do đó, không có gì thực sự sai với việc có một loại chạy phần phổ biến một lần và giữ một số nhà nước.

type House(parcel) = 
    let house = 
    parcel 
    |> inspect 
    |> buildWalls 
    |> buildRoof 

    member x.BuildAndAdvertiseHouse() 
    house 
    |> takePhoto 
    |> advertise 

    member x.BuildAndCompleteHouse() = 
    house 
    |> paintWalls 
    |> addFurniture 

Điều này là tốt trong F #, nhưng tôi nghĩ tôi thích cách tiếp cận chức năng hơn với chức năng build.

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