从`.json`文件读取的通用函数

Ste*_*ven 1 f# json.net

所以,我可以随便写一个任意类型JSONNewtonsoft.Json:

type X = {
Number: decimal
Sequence: decimal
NumList: decimal list
}

let createItem (n, s, nL) = 
    {Number = n; 
    Sequence = s; 
    NumList = nL}

let items =
    [
        (1M, 1M, [1M; 2M; 3M])
        (2M, 2M, [2M; 4M; 6M])
        (3M, 3M, [3M; 6M; 9M])
    ]
    |> List.map createItem

open Newtonsoft.Json
open System.IO

let writeToJson (path: string) (obj: 'a) : unit =
    let serialized = JsonConvert.SerializeObject(obj)

    File.WriteAllText(path, serialized)

writeToJson "xList.json" items    
Run Code Online (Sandbox Code Playgroud)

如何编写足够通用的函数以便我可以读取JSON文件?换句话说,我想要像:

let readFromJson (path: string) (t: 'T) = 
    let convertToQr = File.ReadAllText(path)

    Newtonsoft.Json.JsonConvert.DeserializeObject<t list>(convertToQr)
Run Code Online (Sandbox Code Playgroud)

其中第二个参数是Type对象的path,但我不知道该怎么做.如果我尝试按原样使用此函数,则会出现编译器错误.

如何在上面的第二个参数中声明所包含的东西的类型path?我可以吗?

Fyo*_*kin 5

明确定义时,通用参数在函数名称后面的尖括号中写入,在常规参数之前:

let readFromJson<'T>(path: string) =
   let convertToQr = File.ReadAllText(path) 

   Newtonsoft.Json.JsonConvert.DeserializeObject<'T list>(convertToQr)
Run Code Online (Sandbox Code Playgroud)

用法:

readFromJson<string> "/some/file.json"
Run Code Online (Sandbox Code Playgroud)

或者,您可以指定函数的返回类型,并让编译器为您推断所有通用参数和参数:

let readFromJson(path: string) : 't list =
   let convertToQr = File.ReadAllText(path) 

   Newtonsoft.Json.JsonConvert.DeserializeObject(convertToQr)
Run Code Online (Sandbox Code Playgroud)

这里,编译器知道泛型参数DeserializeObject必须是't list,因为它的结果是从中返回的readFromJson,结果类型readFromJson是显式声明的't list.类似地,仅通过注意函数定义中的泛型类型,编译器将推断该函数具有一个泛型参数.

以类似的方式,您可以让编译器在调用函数时推断出所需的类型:

// call inferred to readFromJson<string>, because that's the required return type
let s: string list = readFromJson "/some/file.json"   
Run Code Online (Sandbox Code Playgroud)