2016-10-25 2 views
3

의 추론 다음 코드에서는 두 개의 인터페이스를 정의하며 두 번째 인터페이스는 첫 번째를 형식 매개 변수로 사용합니다. 그러나이 코드는 "유형 매개 변수 'a'가 정의되지 않았습니다"라는 오류를 제공합니다. F # '는이'정보 '가 우선'에 포함되어 있기 때문에 ISecond이 도출 될 때 어떤 유형 추론 할 수없는 이유중첩 된 일반 형식 f #

type IFirst<'a> = 
    abstract Data : 'a 

type ISecond<'First when 'First :> IFirst<'a>> = 
    abstract First : 'First 
    abstract SomeData : 'a 

내 질문은? 예를 들어 다음 코드에서 컴파일러는 'a'가 문자열임을 유추 할 수 있습니다.

type First() = 
    interface IFirst<string> with 
     member x.Data = "" 

type Second() = 
    interface ISecond<First> with 
     member x.SomeData = "" 
     member x.First = First() 

이 문제를 해결할 수있는 방법이 있습니까? 또는 ISecond가 두 가지 매개 변수를 사용해야합니까?

EDIT : 저는 ISecond가 두 가지 유형의 매개 변수를 사용할 수 있음을 알고 있습니다. (처음 질문의 마지막 줄을 기록하십시오). 그것은 분명 무슨 뜻인지 다음 코드 그것은 오류를 제공

type IFirst<'a> = interface end 

type ISecond<'First, 'a when 'First :> IFirst<'a>> = interface end 

type First() = 
    interface IFirst<string> 

type Second() = 
    interface ISecond<First, int> 

을 고려하려면 "이 표현은 형식 문자열을 것으로 예상했지만 여기에 int 형이있다"컴파일러 '는이'문자열입니다 것을 알고 의미, 아직까지는 그것을 그대로 선언해야합니다. 이것이 왜 그런지와 두 번째 유형 매개 변수를 지정하지 않고 해결 방법이 있는지 여부를 알고 싶습니다.

+1

두 번째 매개 변수를 추가해야합니다. -''a'가 범위에 포함되어 있지 않습니다 (실제로는 유추에 관한 것이 아니라 유형의 구조에 관한 것입니다). – kvb

답변

3

난 당신이 두 개의 서로 다른 질문으로 융합 한 생각한다. 하나는 다음과 같습니다.

유형 정의의 일반 매개 변수는 모두 명시 적이어야합니까?

대답은 예입니다. 이것은 타입 유추와는 아무런 관련이 없습니다. F #에서 타입 정의가 작동하는 방식 일뿐입니다. 'a 유형 매개 변수는 ISecond의 매개 변수이기도 한 IFirst<_>에 대한 인수로만 사용할 수 있습니다.

다른 질문은 : 하위 유형을 정의 할 때

컴파일러는 슈퍼 형의 형태 파라미터를 추론 할 수 있습니까?

여기에 대한 대답은 약간 더 미묘합니다. 클래스 유형을 정의 할 때 모든 유형 매개 변수를 지정하는 구문 요구 사항이라는 대답이 있습니다.당신이 뭔가하려고하면 다음과 같습니다

let second() = { new ISecond<_,_> with 
        member x.SomeData = "" 
        member x.First = First() } 

:

type Second() = interface ISecond<First,_> with ... 

을 당신은 매개 변수가 문제없이 유추 할 수있는 다른 컨텍스트가,

error FS0715: Anonymous type variables are not permitted in this declaration 

그러나 오류 메시지가 나타납니다 오브젝트 표현식을 사용할 때 두 매개 변수 모두 유추 될 수 있다는 것을 알 수 있습니다.

+0

니스, 당신의 솔루션은 내가 찾고있는 솔루션이었습니다. 익명 형식을 형식 선언에 사용할 수없는 특별한 이유가 있습니까? –

+1

@AmirVakili - 좋은 질문입니다.하지만 불행히도 저는 답을 모릅니다. 매개 변수가 충분하지 않은 경우 개체 표현식의 경우 결과는 일반적 일 수 있지만 형식 정의에서 의미가 없습니다 (따라서 특정 경우에 오류가 발생해야합니다). 그러나 좀 더 일반적으로 기능이 빠진 경우 _why_에 대한 답은 종종 특정 차단제가 있다는 것보다는 "구현 된 사람이 없습니다"라는 것입니다. – kvb

+0

오케이. 모든 도움 주셔서 감사합니다;) –

4

ISecond에 대한 정의가 잘못되었습니다. 유형을 'a으로 지정하고 있지만 정의하지는 않았습니다. 즉, ISecond은 실제로 두 개의 일반 매개 변수 - 'First'a을 가졌지 만 그 중 하나만 정의했습니다.

type ISecond<'a, 'First when 'First :> IFirst<'a>> = 
    abstract First : 'First 
    abstract SomeData : 'a 

을하지만, 물론, 당신은뿐만 아니라 Second의 당신의 정의를 수정해야합니다 :

이 작동 할

type Second() = 
    interface ISecond<string, First> with 
     member x.SomeData = "" 
     member x.First = First()