2017-10-16 8 views
1

안녕하세요. 저는 F #에서 프로그래밍을 시작했고 타입 문제에 집착하고 있습니다.매개 변수가 항상 DerrivedType이되도록 제한된 방식으로 사용되었습니다.

member private this.UpdateStats<'T when 'T :> StatisticsBase>(passed: bool, stats: 'T) = 
     //more stuff.. 
     stats 

내가 이런 식으로 전화 해요 : :

this.UpdateStats<GroupStats>(true, GroupStats(Id = Guid.NewGuid())) 

컴파일러는 말한다 :

enter image description here 매개 변수가 그것을 제약하는 방법으로 사용되어왔다 나는이 기능이 항상 GroupStats가되어야합니다.

GroupStats는 StatisticsBase에서 상속됩니다. StatisticsBase에서 상속 한 모든 엔티티에서이 함수를 사용할 수 있도록하려면 어떻게해야합니까?

유형 :

[<AllowNullLiteral>] 
type StatisticsBase() = 
    member val Id = String.Empty with get,set 

[<AllowNullLiteral>] 
type GroupStats() = 
    inherit Stats() 

StatisticsBase 실제로는 C# 형식에서 상속 및 저장소에 사용되는,하지만 난 더 다시 한

+0

더 많은 코드를 표시해야합니다. 내가 설명한 최소한의 구현으로는 경고를받지 못합니다. 나는'UpdateStats'의 코드가 당신이 들려주는만큼 간단하지 않다고 생각합니다. –

답변

3

위의 코드 오류를 재현 할 수 있으며 앞으로, 우리가왔다

type SomeType() = 
    member this.M2() = 
     this.M<GroupStats>(true, GroupStats()) 

    member private this.M<'T when 'T :> Stats>(x: bool, t: 'T) = 
     t 

이 코드는 실제로 DESCR를 생성합니다 : 실제 비 작업 코드는이 (: 제공 자세한 내용은 미래를위한 팁) 같은 것을 확인 할 수 ibed 오류. 이것은 F # 형식 유추가 위에서 아래로, 왼쪽에서 오른쪽으로 작동하기 때문입니다. 하지만 예외가 있습니다. 클래스 (및 기타 상호 재조직 정의 그룹)는 형식 추론의 두 가지 패스를 얻습니다. 첫 번째 서명 다음에 본문입니다.

컴파일러가 처음으로 M2 본문을 가로 지르는 경우 M 메서드는 GroupStats을 반환해야한다고 결정합니다. 나중에 컴파일러가 M 본문을 가로 지르면 의 반환 값이 t 매개 변수와 동일하므로 M'T을 반환해야 함을 의미합니다. 그러나 컴파일러는 이미 M2의 본문을 검사하여 이 GroupStats을 반환해야 함을 알고 있으므로 'TGroupStats이어야합니다. MM2 이전에 정의 된 경우

이 발생하지 않습니다 :이 경우, 형식 유추가 처음 M의 신체가 발생하고 올바르게 다음 M2의 몸체와 일치되는, 'T 자사 반환 유형을 결정, 그리고 아무 문제도 없을 것입니다.

위에서 두 가지 해결책을 수립 할 수 있습니다. 먼저, MM2 앞에 정의 할 수 있습니다. 그것의 반환 유형은 첫 번째 패스 후 알려진 될 것이며, 문제가 사라,

member private this.M<'T when 'T :> Stats>(x: bool, t: 'T): 'T = 
     t 

이 방법 : 둘째, 당신은 명시 적으로 M의 반환 유형을 지정할 수 있습니다.

+0

고마워, 내가 뭘 잘못했는지 알아. 처음에 UpdateStats 함수를 선언하고 그 대신에 함수를 호출하면 모든 것이 잘 돌아갑니다.시퀀스가 잘못되었을 때 왜 타입 오류가 발생했는지 설명 할 수 있습니까? 귀하가 답안을 시퀀스 문제로 업데이트하면 답을 표시합니다. 다시 한 번 감사드립니다! –

+0

답변을 업데이트했습니다. –