1

このエラーはどこから来ているのだろうか。これがコードで、fsahrpxDSLを使用するTPの下にあります

更新:「解決策」を見つけました。これは、外部でキャストを実行し、キャストごとに1つのゲッターを作成することです。なぜこれが起こるのか、またはより良い解決策があるのか​​誰かが知っているなら、私は知ってうれしいです。(ProvidedTypes-0.2.fsの限定引用パターン?)

編集:私の必死の失敗した試みはそれほど面白くありません。たとえば、2つの興味深いものは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
4

2 に答える 2

3

F#タイププロバイダーのプロパティとメソッドの引用符で囲まれたコードに表示される式は非常に限られています。タイププロバイダーを作成するときに同じ問題に直面しました。現時点では正確な仕様はないと思いますので、ソースコードを確認するか、実験するしかありません。

その理由は、F#引用符のILへのコンパイルがまだ完全に実装されていないため、型プロバイダーのコードジェネレーターは、それを機能させるのに十分な基本機能を実装しているだけである可能性があります。

プロバイダーを作成するとき、私は通常、すべての「ランタイム」コードがモジュールに配置され、メソッドまたはプロパティに渡される引用符で囲まれたコードがこのランタイムを呼び出すというパターンに従います。引用は単なるメソッド呼び出しであるため、これは機能します。何かのようなもの:

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

プロパティをプロバイダーに追加する場合、引用符は次のように呼び出します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

編集:タイププロバイダーのコード生成が内部でどのように機能するかについてはあまり詳しくありませんが、驚くべき場合は、ほとんどの場合、タイプの何かで<@ otwo @>、または同様に機能します。otwoSystem.Object

タイププロバイダーが引用からコードを生成する場合、式のILコードを生成する必要がありますotwo。ただし、otwoがタイプの場合System.Object、オブジェクトを再作成する(または他の方法でオブジェクトをシリアル化する)ILを生成できないため、これは一般的に意味がありません。

このため、F#型プロバイダーメカニズムは(おそらく)ILに簡単に変換できるプリミティブ値(例のような型の値など)のみを許可floatします<@ dtwo @>

于 2012-04-15T14:05:33.280 に答える
2

今後数週間以内に、サンプルのコードプレックスサイトでProvidedTypesAPIの更新/修正を公開する予定です。この問題も解決されます。

于 2012-05-02T21:50:36.960 に答える