2017-02-03 5 views
4

"형식을 따옴표 리터럴로 연결할 때 형식이 일치하지 않습니다."라는 오류를 제공하는 형식 공급자가 있습니다.유형 공급자의 호출에 대한 견적에서 함수를 호출하는 방법은 무엇입니까?

작은 문맥에서 문제를 재현하기 위해 아래 코드를 추출했습니다.

let f (s : string) : string = s //some dummy implementation 

let t = ProvidedTypeDefinition(asm, ns, "Root", Some typeof<obj>) 
let ctor = ProvidedConstructor(parameters = [], 
           InvokeCode = (fun args -> <@@ "root" :> obj @@>)) :> MemberInfo 

let prop = ProvidedProperty(propertyName = "SomeProperty", 
          parameters = [], 
          propertyType = typeof<string>, 
          GetterCode = (fun args -> <@@ f %%(args.[0]) @@>)) :> MemberInfo 

do t.AddMembers [ctor; prop] 
    t.SetBaseType typeof<obj> 

... 내가

let root = Provided.Root() 

let a = root.SomeProperty 

같은 유형의 공급자를 사용할 때 오류 얻을 :

Error: The type provider 'typeproviders.providerpoc+MyProvider' reported an error in the context of provided type 'typeproviders.providerpoc.Provided.Root', member 'get_Menu'.

The error: Type mismatch when splicing expression into quotation literal.

The type of the expression tree being inserted doesn't match the type expected by the splicing operation.

Expected 'System.Object', but received type 'System.String'.

Consider type-annotating with the expected expression type, e.g., (%% x : string) or (%x : string).. Parameter name: receivedType.

어떻게 함수를 호출 할 수 있도록 견적을 쓸 수 있습니다 인용구 안에?

감사합니다.

+1

오류 메시지에서 알 수있는대로 예상되는 유형의 주석을 달았습니까? –

+0

@FyodorSoikin - 'string'부분이 실제 유형 불일치와 관련이 없으며 _received_ 유형이 아닌 _expected_ 유형을 나타내므로 메시지가 약간 오도합니다. 그래서 당신은 실제로'%% (args. [0] : obj)'를 사용할 필요가 있습니다. 그러나'f'가 문자열을 기대하기 때문에 아무것도 수정하지 않습니다. Tomas의 대답은이 문제를 해결할 올바른 방법을 보여줍니다. – kvb

답변

6

오류 메시지가 의미하는 것은 유형의 인용식이 예상되는 곳에 obj 유형의 인용 식을 지정한다는 것입니다.

제가 제공된 속성의 GetterCode을 만드는 경우가 발생한다고 판단 : 여기

GetterCode = (fun args -> <@@ f %%(args.[0]) @@>) 

args 각 식 형 obj이다 인용 식 배열이지만 함수 f 문자열을 기대하고 그래서 형 string

트릭을 할해야 objstring로 전환 할 타입 변환을 추가해야 %%를 사용하여 구멍을 작성 인용 :

GetterCode = (fun args -> <@@ f (unbox<string> (%%(args.[0]))) @@>)