2017-12-06 30 views
1

に機能するために、私は2つのJsonProviderの種類があります。パスJsonProviderは、F#の

type Provider1 = JsonProvider<"""{structure}"""> 
type Provider2 = JsonProvider<"""{}structure2"""> 

私はこれらのいずれかを受け入れ、提供JsonProvider、このようなものを使用してJSONを解析することができます機能を持っているしたいのですが:あなたが静的に解決タイプパラメータ(SRTPs)とインライン関数を定義することができ

let parseUsingSpecificProvider json (provider : JsonProvider<GENERIC>) = 
    provider.Parse json 

答えて

2

(コンパイルしない擬似コード):

let inline parseUsingSpecificProvider json (provider:^T) = 
    (^T : (static member Parse : string -> _) json) 

// tests 
#r @"packages\FSharp.Data\lib\net40\FSharp.Data.dll" 
open FSharp.Data 

type Provider1 = JsonProvider<""" { "name":"John"   } """> 
type Provider2 = JsonProvider<""" { "name":"John", "age":94 } """> 

let x = parseUsingSpecificProvider (""" { "name":"Tomas", "age":4 } """) Unchecked.defaultof<Provider1> 
let y = parseUsingSpecificProvider (""" { "name":"Tomas", "age":4 } """) Unchecked.defaultof<Provider2> 

したがって、静的メソッドParseが入力として文字列を受け入れるすべてのタイプで動作します。

0

関数プログラミングでは、「単一関数インタフェース」を関数自体に置き換えることが一般的です。私。代わりにParseメソッドを持つパーサに渡すの、ちょうど最初のクラス値としてParse関数を使用する:あなたが提供するタイプのいくつかの方法が必要な場合は、例えば使用することができ

#r @"packages\FSharp.Data\lib\net40\FSharp.Data.dll" 
open FSharp.Data 

type Provider1 = JsonProvider<""" { "name":"John"   } """> 
type Provider2 = JsonProvider<""" { "name":"John", "age":94 } """> 

let parse parseFn json = 
    parseFn json 

let p1 = parse Provider1.Parse """{ "name": "Not John" }""" 
let p2 = parse Provider2.Parse """{ "name": "Not John either", "age": 12 }""" 

type Parser<'b> = { 
    Parse : string -> 'b 
    GetSample : unit -> 'b 
} 

let parseUsing parser text = 
    printfn "Parsing things like %A" <| parser.GetSample() 
    parser.Parse text 

let parser1 = { Parse = Provider1.Parse; GetSample = Provider1.GetSample } 
let parser2 = { Parse = Provider2.Parse; GetSample = Provider2.GetSample } 

let p1' = parseUsing parser1 """{ "name": "Not John" }""" 
let p2' = parseUsing parser2 """{ "name": "Not John either", "age": 12 }""" 

SRTPは強力で(クール)、その使用は制限されるべきです。過度に使用するとコンパイラが遅くなり、コードを理解しにくくなります。