F #

2013-06-25 3 views
22

에서 차별 유니온 대 레코드 유형을 사용해야하는 경우 복잡한 예제로 넘어 가기 전에 F # clear의 기본 사항을 익히려고합니다. 제가 배우는 자료에는 Discriminate Unions와 Record Types가 있습니다. 두 가지 모두에 대한 자료를 검토했지만, 왜 우리가 다른 것을 사용하는지에 대해서는 여전히 분명하지 않습니다.F #

내가 만든 장난감 예제의 대부분은 두 가지 모두에서 구현할 수있는 것 같습니다. 기록은 내가 C#에서 개체로의 생각에 가까운 것 같다,하지만 난

  • 는 ... F 번호 그래서

    을 이해하는 방법으로 C#을 매핑에 의존하지 않도록 노력하고 있어요 다른 하나를 사용하는 분명한 이유가 있습니까?

  • 하나의 적용 사례가 있습니까?

  • 다른 기능은 없지만 은 없나요?

+1

이 페이지에는 http://msdn.microsoft.com/en-us/library/dd233205.aspx 끝에 간단한 문단이 있습니다. –

답변

25

기록은 '및'이며, 차별화 된 공용어는 '또는'입니다. 이 문자열이나 int 형 중 하나만입니다 값이있는 동안

type MyRecord = { myString: string 
        myInt: int } 

: 이 문자열과 INT는

type MyUnion = | Int of int 
       | Str of string 

이 가상의 게임은 타이틀 화면에서 할 수 있습니다 , 게임 중 또는 최종 점수 표시 중 하나만 선택할 수 있습니다. 당신이 C 번호에서 오는 경우

type Game = 
    | Title 
    | Ingame of Player * Score * Turn 
    | Endgame of Score 
+0

그래서 DU에는 Game을 확장하는 결합 된 유형을 만드는 방법이 있습니까? 예를 들어 | InGameTitle of Title * Ingame. 즉, 제목 * 플레이어 * 점수 * 터플을 포함하는 튜플 –

+0

@ 크리스 : 그것은 단지 질문을 구걸합니다 : 왜 당신이 원할 것입니까? – ildjarn

+0

@ildjarn 당신은 맞습니다. 처음 의견을 쓸 때, 나는 하위 사용자의 목적을 완전히 이해하지 못했습니다. MisterMetaphor의 대답은 제가 로버트처럼 사용하는 이유를 이해하는데 도움이되었습니다. –

7

, 당신은 추가 값 밀봉 클래스 등의 기록을 이해할 수 : 기본적으로

  • 불변의
  • 패턴 일치을 기본적
  • 쉬운에 의해
  • 구조 평등

구분 된 공용체 대체물 등을 인코딩합니다.

type Expr = 
    | Num of int 
    | Var of int 
    | Add of Expr * Expr 
    | Sub of Expr * Expr 

다음과 DU는 상기 판독 :식이 어느 정수 또는 변수, 또는 두 식 또는 두 식 사이 감산의 추가이다. 이러한 경우는 동시에 발생할 수 없습니다.

레코드를 생성하려면 모든 필드가 필요합니다. DU를 레코드 내부에 사용할 수도 있고 반대로 DU를 레코드 내부에 사용할 수도 있습니다.

type Name = 
    { FirstName : string; 
     MiddleName : string option; 
     LastName : string } 

위 예제에서는 중간 이름이 선택 사항임을 보여줍니다.

F #에서는 튜플이나 레코드로 데이터를 모델링하기 시작합니다. 고급 기능이 필요할 때 클래스로 이동할 수 있습니다.

반면에 차별화 된 공용체는 대안을 모델링하는 데 사용되며 상호 배타적 인 경우는입니다.

+0

감사. 이 답변과 다른 두 가지 사실은 하위 사용자가 일종의 OR 관계임을 나타냅니다. 그러나이를 이해하면 단일 하위 사용자는 여러 값을 가질 수 있습니다. 즉,'type Name'은'FirstName, MiddleName, LastName'에 대한 값을 가질 수 있습니다. 이것은 여전히 ​​모든 필드에 대한 값을 가진 레코드와 모든 필드에 대한 값을 가진 DU의 차이점에 대해서는 조금 확신 할 수 없습니다. DU가 추론 할 수있는 어떤 형태의 추론이나 조작이 가능하지 않습니까? 아니면 불변의 속성이 여기에 차이점이 있습니까? –

11

사용 기록 데이터베이스 레코드 또는 일부 모델 개체와 같은 몇 가지 속성에 의해 설명되어 복잡한 데이터 (함수형 프로그래밍 이론라는 제품 유형) : 사용 노조를 차별

type User = { Username : string; IsActive : bool } 

type Body = { 
    Position : Vector2<double<m>> 
    Mass : double<kg> 
    Velocity : Vector2<double<m/s>> 
} 

(라고 합 유형) 데이터 가능한 값을 열거 할 수 있습니다. 예를 들면 : 판별 조합 값의 가능한 값도 함께 사용할 수 있음은

type NatNumber = 
| One 
| Two 
| Three 
... 

type UserStatus = 
| Inactive 
| Active 
| Disabled 

type OperationResult<'T> = 
| Success of 'T 
| Failure of string 

주 - 조작 결과는 동시에 하나 또는 SuccessFailure 있지만 둘 수있다.

은이 같은 작업의 결과를 인코딩하는 레코드 유형을 사용할 수

type OperationResult<'T> = { 
    HasSucceeded : bool 
    ResultValue : 'T 
    ErrorMessage : string 
} 

그러나 작동 불량의 경우는 ResultValue이 이해가되지 않습니다이다.

match result with 
| Success resultValue -> ... 
| Failure errorMessage -> ... 

을 그리고 당신은 패턴 우리의 작업 유형의 레코드 유형 버전과 일치하는 경우는 적은 의미 할 것 : 그래서,이 유형의 차별 노조 버전에 일치하는 패턴은 다음과 같을 것이다

match result with 
| { HasSucceeded = true; ResultValue = resultValue; ErrorMessage = _ } -> ... 
| { HasSucceeded = false; ErrorMessage = errorMessage; ResultValue = _ } -> ... 

을 그것은 장황하고 어색하고, 아마 덜 효율적 일 것입니다. 나는이 느낌이들 때 아마 당신이 틀린 도구를 사용하고 있다는 암시 일 것이라고 생각합니다.

+0

이 응답을 보내 주셔서 감사합니다. 나는 이제 DU가 특별한 의미를 갖는 곳을 본다. –

2

하나의 (약간 결함이있는) DU를 이해하는 것은 공상적인 C# "유니언"이라고 생각하는 반면 레코드는 일반 개체 (여러 독립 필드 포함)와 비슷합니다.

DU를 보는 또 다른 방법은 상위 수준 DU 유형이 추상 기본 클래스이고 하위 DU가 하위 클래스 인 DU를 2 수준 클래스 계층 구조로 보는 것입니다. 이 뷰는 컴파일러에 의해 숨겨져 있지만 실제로는 실제 .NET 구현에 가깝습니다.

+0

OO 상속 계층과의 중요한 차이점 중 하나는 DU의 여러 사례가 태그에 불과하지만 다른 (하위) 유형이 아니라는 점입니다. 가끔 신참을 혼란스럽게합니다. – Frank