所以我把它作为一个剧本:
#r @"..\packages\FSharp.Data.2.4.2\lib\net45\FSharp.Data.dll"
#r "System.Xml.Linq.dll"
open FSharp.Data
// provide some URL, file path, or raw JSON sample
// that can be used at compile time to generate types
type Json = JsonProvider<"example.json">
// at runtime, load up new sample matching that schema
let response = Http.Request("https://world.openfoodfacts.org/api/v0/product/737628064502.json")
let samples = Json.Parse(response.Body.ToString())
我想做的是:
在c#中会是这样的:
public static Models.Product UpdateFromRemote(this Models.Product Product, string Language, string Barcode)
{
//the f# code included above to fetch the remote source
//only the url is fetched from:
// string.Format("https://{0}.openfoodfacts.org/api/v0/product/{1}.json",Language,Barcode);
Product.Title = samples.Product.GenericName; //samples is the fetched resource from the f# code
return Product;
}
f#中的逻辑是什么?
目前我有这个(这还不正确/完整)
namespace LookupByBarcode.openfoodfacts.fSharp
open FSharp.Data
type model(Language,Barcode) =
member this.Language = Language
member this.Barcode = Barcode
module getRemote =
type json = JsonProvider<"example.json">
let response = json.Load("https://world.openfoodfacts.org/api/v0/product/737628064502.json")
let Title = response.Product.ProductNameEn
答案 0 :(得分:3)
如果您有一个无法修改的外部DLL定义了类型Product
,那么就没有简单的方法可以向产品添加新字段。我认为最优雅的F#方式是将其包装在添加附加信息的记录中:
type MyProduct =
{ Product : Product
Language : string
Barcode : string }
接下来,如果要更新MyProduct
值以使其反映新获得的标题,则它取决于基础Product
类型的外观。它是可变的还是不可变的?
要获得惯用的F#代码,您需要创建一个返回克隆的函数。这对于F#记录很容易,但对于C#对象可能很难。它可能看起来像这样:
let updateProduct newTitle newLanguage myproduct =
// Create a new `Product` with changed title. If you want to avoid mutation,
// you need to create a new instance, which might be tedious for C# objects
let op = myproduct.Product
let np =
Product
(Title = newTitle, OtherThing = op.OtherThing,
YetAnotherThing = op.YetAnotherThing)
// Now create a new updated F# record - this is much easier
{ myprodcut with Product = np; Language = newLanguage }
使用F#中的C#可变对象惯用工作会很棘手,所以我的建议是在F#中定义域模型,这样你就可以在任何地方使用漂亮的F#with
关键字。也就是说,改变C#对象也是有意义的 - 如果这是你真正想做的事情。