2013-08-29 3 views
5

필자는 순수 함수의 두 가지 함수를 가지고 있습니다. 첫 번째 함수는, 소포 소요 그 위에 집을 구축하고, 잡지에 광고를 사진을 촬영 : 두 번째 기능은 또한 소포 소요 그 위에 집을 빌드 및 함수 언어로 순수 함수를 작성할 때 불필요한 계산을 피하는 방법은 무엇입니까?

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

는 마무리를 추가 터치 :

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

두 함수가 순수한 함수이기 때문에 두 함수가 순수하다는 것도 분명합니다. 이제 소포가 있는데, niceParcel라고 말하면 두 함수를 모두 적용하고 싶습니다. 그러나 처음 세 하위 함수는 계산에 많은 시간이 걸리고 두 함수간에 공유되므로 두 번 계산되는 것을 피하고 싶습니다.

내 코드를 어떻게 리팩터링합니까? 이러한 불필요한 계산을 피하고 명확한 의미를 갖는이 멋진 함수를 유지하면서 어떻게해야합니까?

+1

만약'parcel'이 generic 타입이 아니라면'let buildAnd ... = inspect >> buildWalls >> ... >> advertise'를 사용하여 더 관용적 인 코드를 만들 수 있습니다. (적당한 들여 쓰기로) –

+1

Regarding 질문, 두 함수를'build','advertise','completeHouse'라는 세 개의 함수로 나누지 않으시겠습니까? –

+0

그들은 프로그램의 다른 부분에서 사용할 수있는 하나의 엔티티를 형성합니다. 물론 분리 될 수 있지만이 엔티티는 손실됩니다. 이 경우, 당신이 그것을 사용하기를 원한다면, 당신은 내면의 작동을 알아야 할 것입니다. 즉 그것이 처음으로 건설 된 다음 완성되거나 광고되는 것입니다. 나는 당신이 내적 활동을 알아야한다는 것을 피하고 싶다. – Tuur

답변

5

다른 의견에서 언급했듯이 최선의 방법은 공통 부분을 build 기능으로 바꾸는 것입니다. 다른 목적으로이 함수를 사용하지 않으려는 경우에도 기능 코드를 구조화하는 명확한 방법입니다.

F #에서는 부분적으로 빌드 된 하우스를 나타내지 만 내부를 노출하지 않는 유형을 정의 할 수 있습니다.

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

    let buildAndAdvertiseHouse house = 
    house 
    |> takePhoto 
    |> advertise 

    let buildAndCompleteHouse house = 
    house 
    |> paintWalls 
    |> addFurniture 

당신은 그 사실을 숨길 수 있습니다 :이 라이브러리의 발신자가 부분적으로 구축 집을 구축 build를 사용할 수 있지만, 그들은 그것으로 할 수있는 유일한 것은 당신이 제공하는 두 가지 기능을 사용하는 것을 의미한다 당신이 &을 다양한 방법으로 광고하기 전에 집을 지을 필요가 있습니다. 예를 들어 일반적으로 한 번에 두 가지 작업을 모두 수행하는 경우 세 가지 기능을 모두 호출하는 함수를 정의 할 수 있습니다. 라이브러리 사용자는이 함수를 사용하거나 집 건물에 대해 조금 더 배우고 세 가지 함수를 사용할 수 있습니다 더 세밀한 제어가 필요하다.

또 다른 접근법은 기능을 간단한 유형으로 마무리하는 것입니다. F #이 혼합 된 기능적 및 객체 지향적 스타일이므로 공통 부분을 한 번 실행하고 일부 상태를 유지하는 유형을 갖는 것이 실제로 잘못된 것은 아닙니다.

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

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

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

이 F 번호에 괜찮지 만, 나는 내가 build 기능을 가진 기능적인 접근 방식을 선호하는 것 같아요.