내 질문은 이것이다 :F # 유형 제공자 개발 : 방법을 제공 할 때 변수 번호와 유형의 매개 변수에 액세스하는 방법은 무엇입니까?
어떻게 디자인 타임에 그 표현의 수와 유형을 모를 때 나는 인용으로 목록에서 식을 스플 라이스 할 수 있습니까?
하단에는 유형 제공자의 전체 코드가 포함되어 있습니다. (. 내가 문제를 보여주기 위해 아래로 개념을 제거했다) 내 문제는이 라인에서 발생 람다 매개 변수 arg
에
let func = ProvidedMethod((*...*), InvokeCode = fun args ->
<@@ let stringParts =
args
|> List.mapi (fun i arg ->
if paramTypes.[i] = typeof<int> then
sprintf "%i" (%%arg: int)...
, 나는 다음과 같은 오류 얻을 : 내가 할 수있는
error FS0446: The variable 'arg' is bound in a quotation but is used as part of a spliced expression. This is not permitted since it may escape its scope.``
를 ' (비록 컴파일 타임에 알려질지라도) 값의 수와 타입이 프로 바이더 디자인 타임에 알려지지 않을 때 매개 변수 값을 "추출"하도록 코드를 작성하는 방법을 이해해야합니다.
printfn "%A" (%%args.[0]: int)
그러나 나는 내 obj list
에 Expr list
입력에서 얻을 방법을 알아낼 수 없습니다 : 내가 디자인 타임에 매개 변수의 존재와 유형을 알고 수행 할 때
,이 작업을 수행 할 수 있습니다 견적.
여기 전체 Provider 형 코드입니다 : 최소한의 예를 들어
[<TypeProvider>]
type SillyProviderDefinition(config: TypeProviderConfig) as self =
inherit TypeProviderForNamespaces()
let sillyType = ProvidedTypeDefinition(THIS_ASSEMBLY, NAMESPACE, "SillyProvider", Some typeof<obj>)
do sillyType.DefineStaticParameters([ProvidedStaticParameter("argTypes", typeof<string>)], fun typeName args ->
let retType = ProvidedTypeDefinition(typeName, Some typeof<obj>)
let paramTypes =
(args.[0] :?> string).Split([|'|'|])
|> Array.map (function
| "int" -> typeof<int>
| "string" -> typeof<string>
| x -> failwithf "Invalid argType %A. Only string or int permitted" x)
let parameters =
paramTypes
|> Array.mapi (fun i p -> ProvidedParameter(sprintf "arg%i" i, p))
|> Array.toList
let func = ProvidedMethod("Stringify", parameters, typeof<string>, IsStaticMethod = true, InvokeCode = fun args ->
<@@ let stringParts =
args
|> List.mapi (fun i arg ->
if paramTypes.[i] = typeof<int> then
sprintf "%i" (%%arg: int)
elif paramTypes.[i] = typeof<string> then
(%%arg: string)
else
failwith "Unexpected arg type")
//printfn "%A" (%%args.[0]: int)
String.Join("", stringParts) @@>)
do retType.AddMember func
do sillyType.AddMember retType
retType)
do self.AddNamespace(NAMESPACE, [sillyType])
코드가 유형 공급자 클래스의 컨텍스트에서 어디에 표시 될 수 있습니까?컴파일을 시도했지만 컴파일하려고했지만 다음과 같은 오류가 발생했습니다 : ''오류 FS0193 : 모듈/네임 스페이스 'StartupCode $ TypeProviderPain>. $ Library1'컴파일 유닛 'TypeProviderPain'에서 가져 오지 않았습니다. 모듈 이름 또는 형식을 포함합니다. 'formatInt @ 47''' ''scripty.fsx (7,9) : 오류 FS1109 : 어셈블리의'. $ [email protected] '형식에 대한 참조 'TypeProviderPain'이 발견되었지만 형식이 해당 어셈블리에서 발견되지 않았습니다. ' –
"formatInt"및 "formatString"을 자체 모듈로 이동하여 런타임 오류를 없앨 수있었습니다. 유사한 오류를 피하기 위해 "String.concat"을 "String.Join"으로 대체해야했습니다 :''error FS0193 : 컴파일 유닛 'FSharp.Core'의 모듈/네임 스페이스 'Microsoft.FSharp.Collections'에 namespace, module 또는 'StringModule'''을 입력하십시오. 이러한 단계를 수행 한 후에는 ** 유형 공급자를 실행할 수있었습니다 **. –
그런 종류의 오류는 슬프게도 평범한 유형의 공급자 통증입니다 ... 다행히 생각해보십시오! –