2012-04-15 1 views
1

이 오류의 출처는 궁금합니다. 다음은 코드이며 fsahrpx를 사용하는 TP 아래입니다."Unsuported Constant Type : System.double"오류를 제공하는 유형 공급자 #

업데이트 : 캐스트를 외부에서 수행하고 캐스트 당 하나의 getter를 만드는 '솔루션'을 발견했습니다. 왜 이런 일이 발생하는지 또는 더 나은 해결책을 알고 있다면 기꺼이 알게 될 것입니다. 합니다 (ProvidedTypes-0.2.fs 제한된 인용 패턴?)

편집 : 내 필사적는 시도가 너무 재미없는 실패했습니다. 두 가지 흥미로운 것은 Test93 또는 Test92입니다. 왜 그들은 실패 할까? 갱신

가장 논쟁을 좋아하는 경우 90,91,92,93

module Module = 
    open System.Reflection 
    open Samples.FSharp.ProvidedTypes 
    open FSharpx.TypeProviders.DSL 
    open Microsoft.FSharp.Core.CompilerServices 

    type ReflectiveBuilder = static member Cast<'a> (args:obj) = args :?> 'a 
     static member BuildTypedCast lType (args: obj) = 
      typeof<ReflectiveBuilder> 
       .GetMethod("Cast") 
       .MakeGenericMethod([|lType|]) 
       .Invoke(null, [|args|]) 

    let bbgReference ns = 
     erasedType<obj> (Assembly.GetExecutingAssembly()) ns "Reference" 
     |> staticParameter "file" 
      (fun typeName (parameterValues:string) -> 
       let otwo = 2.0 :> obj 
       let dtwo = 2.0 
       let dotwo = otwo :?> float 

       let dcast = ReflectiveBuilder.BuildTypedCast typeof<float> 

       let getter = match otwo with 
           | :? double as d -> (fun args -> <@@ d @@>) 
           | :? string as d -> (fun args -> <@@ d @@>) 

       erasedType<string> (Assembly.GetExecutingAssembly()) ns typeName 
      |+!> ( provideProperty 
         "test90"        //KO 
         (typeof<obj>)     
         (fun args -> <@@ otwo @@>)  
       ) 
      |+!> ( provideProperty 
         "test91"        //KO 
         (otwo.GetType())     
         (fun args -> <@@ otwo @@>)  
       ) 
      |+!> ( provideProperty 
         "test92"        //KO 
         (otwo.GetType())     
         (fun args -> <@@ otwo @@>)  
       ) 
      |+!> ( provideProperty 
         "test93"        //NO 
         typeof<float>     
         (fun args -> <@@ otwo :?> float @@>)  
       ) 

       |+!> ( provideProperty 
          "test"        //OK 
          typeof<float>     
          (fun args -> <@@ dtwo @@>)  
        ) 
       |+!> ( provideProperty 
          "test2"        //NO 
          typeof<float>     
          (fun args -> <@@ dtwo :> obj @@>)  
        ) 
       |+!> ( provideProperty 
          "test3"        //NO 
          typeof<float>     
          (fun args -> <@@ otwo @@>)  
        ) 
       |+!> ( provideProperty 
          "test4"        //NO 
          typeof<float>     
          (fun args -> <@@ otwo :?> float @@>)  
        ) 
       |+!> ( provideProperty 
          "test5"        //OK 
          typeof<float>     
          (fun args -> <@@ dotwo @@>)  
        ) 
       |+!> ( provideProperty 
          "test6"        //OK 
          typeof<float>     
          (fun args -> <@@ dotwo :> obj @@>)  
        ) 
       |+!> ( provideProperty 
          "test7"        //NO 
          typeof<float>     
          (fun args -> <@@ dcast otwo @@>)  
        ) 
       |+!> ( provideProperty 
          "test8"        //OK 
          typeof<float>     
          getter  
        ) 
       |+!> (provideConstructor 
         [] 
         (fun _ -> <@@ "I will be the internal representation" @@>))) 


    [<TypeProvider>] 
    type public CustomTypeProvider(cfg:TypeProviderConfig) as this = 
     inherit TypeProviderForNamespaces() 

     do this.AddNamespace("TEST", [bbgReference "TEST"]) 

    [<TypeProviderAssembly>] 
    do() 

테스트

module Program = 
    open System 

    type t = TEST.Reference<""> 
    let price = t().Test90 
    let price = t().Test91 
    let price = t().Test92 
    let price = t().Test93 
    let price = t().Test //OK 
    let price = t().Test2 //OK 
    let price = t().Test3 //NO OK 
    let price = t().Test4 //NO OK 
    let price = t().Test5 //OK 
    let price = t().Test6 //OK 
    let price = t().Test7 //NO OK 
    let price = t().Test8 //OK 
+0

모르는 경우 Tomas Petricek은 F #을 만든 팀원 중 한 명입니다.Brian McNamara 나 Don Syme이 질문에 무게를 두지 않으면 훨씬 더 권위있는 대답을 얻지 못할 것입니다. –

+0

안녕하세요 @OnorioCatenacci, Tomas 입력에 대한 가치가 매우 높습니다. 새로운 타이핑 기계에 대한 기술을 잘 알고 있습니다.) 여기에서는 Type Provider API의 (실제로) 낮은 레벨을 아는 것이 더 문제라고 생각합니다. 가장자리. (cf 내 사용자 질문에 대한 내 다른 질문을 참조하십시오 .... http : //stackoverflow.com/questions/10357273/type-provider-calling-another-dll-in-f) – nicolas

+0

@OnorioCatenacci 나는 F #을 만든 개발자 중 한 명입니다. 저는 인턴으로 근무했으며 F # 팀과 몇 가지 긴밀한 관계를 맺었습니다.하지만 더 많은 시간을 보내고 유형 공급 업체를 연구하고 구현 한 사람들이 상당수 있습니다. –

답변

2

다음 주에 샘플 코드 플렉스 사이트의 ProvidedTypes API에 대한 업데이트/수정 사항을 게시 할 계획입니다. 이 문제도 해결 될 것입니다.

+0

제공된 유형은 주요 기능입니다. 거친 모서리가 효과적이라는 것을 알면 기쁩니다. 의사 소통은 항상 크게 감사합니다. – nicolas

+0

CodePlex에 최근 게시 한 새 버전을 사용해 볼 수 있습니다. – desco

3

F 번호 속성과 메서드에 대한 인용 부호에 나타날 수있는 표현을 추가 타입 제공자는 상당히 제한적입니다. 타입 제공자를 작성할 때 같은 문제에 직면했습니다. 지금은 정확한 사양이 없다고 생각합니다. 따라서 소스 코드를 살펴 보거나 테스트 해보는 것이 유일한 방법입니다.

이유는 일리노이에 대한 F # 인용문을 컴파일하는 것이 어디서나 완벽하게 구현되지 않았기 때문에 유형 공급자 용 코드 생성기가 작동하기에 충분한 기본 기능을 구현하기 때문일 수 있습니다.

제공자를 작성할 때 일반적으로 모든 "런타임"코드가 모듈에 배치되고 메서드 또는 속성에 전달 된 인용 코드가이 런타임을 호출하는 패턴을 따릅니다. 이것은 인용이 단지 메서드 호출 일 뿐이므로 작동합니다. 뭔가 같은 :

module CultureRuntime = 
    let getCulture (name:string) = 
    // The runtime can contain arbitrary complex F# code 
    CultureInfo.GetCultureInfo(name) 

공급자에 property는 추가, 인용 그냥 호출 CultureRuntime.getCulture :

for culture in CultureInfo.GetCultures(CultureTypes.AllCultures) do 
    let id = culture.Name 
    ProvidedProperty 
    (culture.DisplayName, typeof<CultureInfo>, IsStatic = true, 
     GetterCode = fun args -> <@@ CultureRuntime.getCulture id @@>) 
    |> sampleTy.AddMember 

편집 : I 타입 공급자에 대한 코드 생성이 내부적으로 어떻게 작동하는지 너무 잘 알고 아니에요 하지만 놀랍게 생각하는 경우는 거의 항상 <@ otwo @> 또는 그 유사어로 작동합니다. 여기에서 otwoSystem.Object입니다.

형식 공급자가 따옴표에서 코드를 생성 할 때 식 에 대한 IL 코드를 생성해야합니다. 그러나 otwoSystem.Object 유형 인 경우 객체를 다시 만드는 일리노이를 생성하거나 다른 방법으로 객체를 직렬화 할 수 없으므로 일반적으로 이해가되지 않습니다.

이러한 이유 때문에 F # 유형 공급자 메커니즘 (예 : float의 값인 <@ dtwo @> 예와 같이)은 쉽게 IL로 변환 될 수있는 프리미티브 값만 허용합니다.

+0

도 잘 설명되어 있습니다. 실질적인 조언을 해주셔서 대단히 감사합니다. 코드는 실제로 보이지 않습니다. 2 개월 전처럼 인용문이 아니었지만 Linq는 그 장면 뒤에있었습니다. 결국에는 전체 인용문을 덮을 것이라고 생각합니까? (할 일이있는 것 같지만 실제로 그렇습니다.) – nicolas

+0

이것이 원인이 아니기 때문에 다른 것이 있어야합니다. 당신은 내 예제에서 메소드 호출과 같은 아주 간단한 표현만을 사용합니다. – nicolas

+0

표현식의 컴파일 시간 결과가 선언 된 속성 인 경우 컴파일 시간 유형과 동일하지 않은 경우 오류가 발생하고 어떤 이유로 캐스트가 인용문에서 동일하게 나타납니다. – nicolas