2014-11-25 2 views
8

차별화 된 공용체의 모든 멤버가 공유하는 메소드를 정의하고 싶습니다. 현재 저는 이것을 이렇게 구현했지만 실제로는 더 좋은 방법이 있습니다. 제안?차별화 된 공용체 멤버 메소드

type A = 
    {AData:string} 
    member this.SharedMethod (x:float) : int= ... 
type B = 
    {BData:float} 
    member this.SharedMethod (x:float) : int= ... 
type AB = 
| A of A 
| B of B 

let CallSharedMethod (ab:AB) x = 
    match ab with 
    | AB.A(a') -> a'.SharedMethod x 
    | AB.B(b') -> b'.SharedMethod x 
+0

인스턴스 바인딩이 누락되었습니다 (예 : this.SharedMethod). 그렇지 않으면 작동하지 않습니다. 또한 DU의 인스턴스 (실제로 레코드 유형)에 대한 공유 메소드가 무엇인지에 대한 정보를 추가해야합니다. 왜냐하면 아무 것도하지 않으면 정규 함수를 사용할 수 있기 때문입니다. 나는 네 사건이 아니라고 확신한다. – Gustavo

+0

방법에 따라 나에게 냄새가 난다. 그러나 그렇지 않다면 레코드를 사용하여 인터페이스를 구현할 수 있습니다. – Daniel

+0

예, 죄송합니다. 코드가 구문 상 정확하게 맞지 않았습니다. 나는 패턴에 더 관심이 있습니다. 하위 사용자의 모든 하위 유형이 공통 메소드 이름을 공유한다는 사실을 어떻게 나타낼 수 있습니까? 더 정확한 코드를 편집하겠습니다. –

답변

12

어때?

type AB = 
    | A of string 
    | B of float 

    member self.SharedMethod (x : float) = 
     match self with 
     | A s -> x 
     | B f -> f + x 

는 플로트 매개 변수와 함께 뭔가 다른 일을하기 위해 합 유형 (일명 차별 노동 조합)의 각 변형을한다고 가정합니다. (A float 산출 stringfloat 사이의 유용한 관계가 더 일반적으로 존재하지 않기 때문에) 내가 할 수있는 다른 많은 거기 이후 A의 경우를 들어

은, 그냥 원래의 값을 반환합니다. 당신의 예에서

7

, 당신은 는 인스턴스 멤버로 기록 유형을에게 AB 각을 증강있다. 그러나 레코드 유형을 늘릴 수있을뿐만 아니라 유니온 유형을 추가 할 수도 있습니다 (@ Rodrick의 답변 참조). 이렇게하면, 노동 조합의 증원은 귀하가 요청한 각 사례에 의해 "공유"됩니다. 이 더 명시 적으로 만들려면, 당신의 예를 몇 가지 부분을 이름을 변경 한 : 당신은 개체 브라우저 (또는 ILSpy 같은 디 컴파일러)에서 컴파일 된 코드를 보면

type A = { AData:string } 
type B = { BData:float } 

type AB = 
    | ACase of A 
    | BCase of B 
    member __.SharedMethod x = 0 

let callSharedMethod (ab:AB) x = ab.SharedMethod x 

, 당신은 AB가 컴파일되는 것을 볼 수 있습니다 두 개의 서브 클래스 AB.ACaseAB.BCaseSharedMethod의 기본 클래스는 기본 클래스 AB에 속합니다.

F# 3.0 specification의 섹션 8.5.1 : 연합 유형의 구성원을 참조하십시오.