我可以创建条件文字吗?

时间:2017-08-03 11:39:49

标签: f# literals type-providers

为了创建一个Json提供程序,我需要传递一个带有路径的文字。有几个人从不同的地方开展项目工作,每种情况下的路径都不同。 (实际上只是每条路径的开头)。我试图用模式匹配创建一个文字,但编译器不接受它。还有另一种方法吗?

我失败的尝试如下:

open FSharp.Data

[<Literal>]
let bitbucketRoot = // Error message: This is not a valid constant expression
    let computerName = Environment.MachineName 
    match computerName with
    | "DESKTOP-G3OF32U" -> "C:\\Users\\Fernando"
    | "HPW8" -> @"H:\Dropbox\"
    | _ -> failwith "Unknown computer"

[<Literal>] // Error message: This is not a valid constant expression
let projDataPath = bitbucketRoot + @"Bitbucket\VSProjects\Fractal10\Fractal10\data\" 

[<Literal>] // Error message: This is not a valid constant expression
let jsonPath = projDataPath + "fractal.json"
type PathInfo = JsonProvider<Sample=jsonPath>

2 个答案:

答案 0 :(得分:3)

我建议您将其存储在源代码管理中,并使其成为相对于项目根目录的路径,假设您正在使用公共源代码控制存储库。

或者在公共URL上托管样本。 (我实际上并不推荐这样做,因为将它包含在您的源存储库中允许版本控制并且不公开显示您的数据)

答案 1 :(得分:1)

您无法创建条件文字,因为其他评论指出了它。然而,这是一个相当频繁的用例,处理它的方法如下:

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

[<Literal>]
let JsonSource = __SOURCE_DIRECTORY__ + @"\test.json"

type JSonType = JsonProvider<JsonSource>

let json1 = JSonType.GetSamples()

let anotherPath = @"C:\tmp"
let anotherJson = anotherPath + @"\test.json"
let json2 = JSonType.Load(anotherJson)

__SOURCE_DIRECTORY__指令将指向项目根目录(只显示在REPL中),然后您可以为其添加文件名并使其成为文字。如果你将这个文件签入git仓库,那么检查它的每个人都可以将它放在相对路径中,你可以在生成类型时引用它。实际使用类型或引用完整文件时,您只需使用.Load()方法加载任何文件,这不一定是文字。

实际上有第二种方法,可以根据具体情况为您工作,编译样本,并将其作为.dll分发。您可以参考此内容并直接使用它而无需访问实际文件。请参阅文档末尾的Using the JSON Provider in a Library部分。

我没有尝试在配置文件中引用json,它也可能。