2012-06-23 3 views
4

나는 나의 시나리오를 위해 간단한 예제를 작성했다. 나는 레코드 유형을 SwitchF #의 레코드 메소드

type State = 
    | On 
    | Off 
    with 
     member this.flip = 
      match this with 
      | On -> Off 
      | Off -> On 

type Switch = { State : State } 

를 만든 다음 나는 하나 개의 요소는 내가

let flipMany times switch = 
    [1 .. times] 
    |> List.fold (fun (sw : Switch) _ -> flip sw) switch 
쓰기 많은 연속적인 시간 flip

let flip switch = { switch with State = switch.State.flip } 

변화와 기록의 사본을 생성하는 함수를 작성

레코드로이 두 함수를 메서드로 넣으려는 경우 대신 쓸 내용

type Switch = 
    { State : State } 
    member this.flip = 
     { this with State = this.State.flip } 
    member this.flipMany times = 
     [1 .. times] 
     |> List.fold (fun (sw : Switch) _ -> sw.flip) this 

이 작업에 문제가 있습니까? 똑같이 효율적입니까? 매번 다른 객체에 sw.flip 함수를 호출하는 것이 약간 불편합니다.

편집 : 이것은 내 질문을 설명하기위한 간단한 예일뿐입니다. 내 질문에 기능을 flipManyflipMany 메서드를 사용하여 레코드를 비교하는 방법에 있습니다. 구현은 순진 할 수도 있지만 두 경우 모두 동일합니다.

+2

'flip '에 대한 다중 호출을 통해'flipMany'를 구현할 필요가 없습니다.'times % 2 = 0'은 뒤집지 않는다는 것을 의미합니다. –

답변

9

귀하의 의도는 관용적 인 방법은 옵션 기능 부착 될 객체의 방법에 비해 정적 기능을 비교하는 더 넓은 맥락에서

let flipMany times switch = 
    match (times % 2) with 
    | 1 -> { switch with State = switch.State.flip } 
    | _ -> switch 

type Switch = 
    { State : State } 
    member this.Flip = { this with State = this.State.flip } 
    member this.FlipMany times = 
     match (times % 2) with | 1 -> this.Flip | _ -> this 

로 간단하게 구현할 수있다. 함수는 명시적인 인수를 가지며 짝수 개 아닌 결과 값을 생성하기 위해 인수의 상태, 즉 모든 상태에 종속되어서는 안됩니다. 반대로, 객체 메소드는 클래스의 인스턴스를 암시 적으로 인수로 가져 오며, 인수뿐만 아니라 다른 클래스 필드의 상태를 기반으로 순수한 함수의 idempotency 속성과 일치하지 않는 결과 값을 도출 할 수 있습니다 .

이 차이를 더 잘 느끼려면 F# Components Design Guidelines을 읽고, F# Core libraries design을 조사하는 것이 도움이 될 수 있습니다.

+0

죄송합니다. 내 질문에 명확하지 않은 경우 위의 편집을 참조하십시오. – Panos

+0

나는 본다; 그에 따라 대답을 조정했다. –