所以,假设我有一个CSV文件,其中包含包含Population和Profit列的标题,我想在F#interactive中使用它.我有以下代码:
#r "../packages/FSharp.Data.1.1.10/lib/net40/FSharp.Data.dll"
open FSharp.Data
// load csv header
let cities = new CsvProvider<"cities.csv">()
// how to reach data
let firstRow = cities.Data |> Seq.head
let firstPopulation = firstRow.Population
let firstProfit = firstRow.Profit
Run Code Online (Sandbox Code Playgroud)
我收到F#interactive的错误:
错误FS0039:未定义字段,构造函数或成员"Population"
这对我来说似乎很困惑,因为VS中的intellisense通过CSV类型提供程序从我的数据中获取此列没有任何问题.
此外,我尝试使用相同类型的提供程序创建一个程序,它一切正常.像这样:
open FSharp.Data
[<EntryPoint>]
let main argv =
use file = System.IO.File.CreateText("result.txt")
let csv = new CsvProvider<"cities.csv">()
for record in csv.Data do
fprintfn file "%A" record.Population
0
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?谢谢你的回答.
使用FSharp.Data(Version 2.0.5)中的XML类型提供程序,元素名称与架构中的名称不匹配.
例如,我的XML文件以:
<?xml version="1.0" encoding="utf-8"?>
<WebQuery><Results><Result><PrimaryID>105882365</PrimaryID><CONTACT_ADDRESS_LINE_1 /><CONTACT_ADDRESS_LINE_2 />
Run Code Online (Sandbox Code Playgroud)
但是在F#中,我需要引用CONTACT_ADDRESS_LINE_1
.ContactAddressLine1
Run Code Online (Sandbox Code Playgroud)
关于类型提供者有什么我不明白的吗?为什么F#中的名称与模式中的元素名称不同?
我的F#应用程序具有非常好的F#模型,充分利用了F#类型系统(联合,记录,元组和基元类型).我试图找出将这些数据类型保存到SQL-Server数据库的最佳方法.
让我们做出以下假设:
我想要持久化的中心实体是一个被称为的判别联盟,Task它有大约30个不同的联合案例,每个案例具有完全不同的属性(可能是其他的DU,记录或元组或原始类型),这使得使用矩形关系表格实施起来非常繁琐
我希望每周多次不断改进这些模型,CI会在提交后立即将我的应用程序部署到生产中.同样,使用常规表会使ALTER TABLE语句减慢我的开发和部署速度,并且会增加大量的认知过载,任何新开发人员都会在这个系统上遇到挑战
在进行模型演变后,我应该能够轻松地使用后台进程在线升级我的旧模型,或者从数据库中获取时,使用接近0的停机时间
我应该能够在任意深度查询这些模型,并且我已经接近一百万行来处理,并且这将继续增长.查询速度应该很快,最多为100毫秒
我需要使用SQL Server,因为此应用程序是较大系统的一小部分,我希望任何数据库操作都参与任何正在进行的数据库事务
TaskJSON这是我的第一次尝试 - 将所有内容存储为JSON,识别可查询值,使用SQL Server 2016的新JSON函数将它们存储在索引表中.SQL Server中的JSON函数非常快,但索引这些查询要求我使用持久+计算+索引列或索引视图.
烦恼:
非常难以进化模型,特别是如果我想要进化所有类型X的实例,这些实例可能出现在不同联合情况的不同深度.没有标准化的语言可以指出这些演变
JSON不区分十进制/浮点数/数字,这有时很难处理,我需要自定义格式化程序.小问题,没什么大不了的.
查询语言在任意深度都有些原始,并且这些查询没有索引,因此新查询几乎总是要求我创建计算列或更改索引视图.
将新的索引列添加到索引视图不是ONLINE操作并导致停机,并且很难在CI中自动化
在同一个表中使用PERSISTED COLUMNS有时会导致SQL Server在搜索/选择时没有真正使用它们,而是从头开始重新计算这些值(因为它在查询计划器中没有准确地计算出这个操作的成本)
TaskXML这是我目前的实施.
我编写了自己的自定义XML序列化程序,这使我很容易使用XQuery和SQL Server的xml数据类型列查询数据库
使用功能非常强大的XSLT,模型演变变得轻而易举
问题:
我对我的XML解决方案非常满意 - 我只需要一种方法来加快我的XML查询,我想在这一点上,我已经达到了SQL Server可以提供的极限.
还有其他方法我错过了F#社区试图能够持久保存非常丰富的F#数据模型吗?
嗯...找到一种使用F#更快地读取/写入数据以在该问题 ( https://www.spoj.pl/problems/INTEST/ ) 中获得接受的方法有点具有挑战性。
我的代码(http://paste.ubuntu.com/548748/)得到TLE...
有什么想法可以加快数据读取速度吗?
极端的noob即将学习的问题:我有一个想在我的C#(通用)应用程序中使用的模块。C#应用程序将下载并解压缩包含12个CSV的文件,这些文件将始终遵循相同的格式。因此,我要做的是提前下载CSV,并将它们添加到我的解决方案中,以便CsvProvider <“ thefile.csv”>中引用的文件将在编译时存在。
namespace ExperimentalFSLibrary
module CsvHelper =
open FSharp.Data
let GetCsvA path =
CsvProvider<"thefileA.csv">.Load(path)
Run Code Online (Sandbox Code Playgroud)
然后从我的c#应用程序中调用此命令,如下所示:
var ReceivedCsvA = ExperimentalFSLibrary.CsvHelper.GetCsvA
Run Code Online (Sandbox Code Playgroud)
从F#库获取数据还没有成功
还有一个问题是如何处理十二个不同的文件,因为我必须为CsvProvider指定模板文件,我想我必须编写12个不同的函数?
我在SO周围搜索,发现了让我走到现在的东西,但我碰到了墙。任何帮助,包括健康检查,将不胜感激。
所以,我正在使用XML Type Provider从XML文档创建类型.
XML文件中的一个元素具有以下Date属性:
<Edit Date="06/30/2015 16:57:46"
... />
Run Code Online (Sandbox Code Playgroud)
这当然导致类似这样的类型:
type Edit =
inherit XmlElement
member Date: DateTime
...
Run Code Online (Sandbox Code Playgroud)
有没有办法可以添加以下代码:
member this.LocalTime
with get() =
this.Date.ToLocalTime()
Run Code Online (Sandbox Code Playgroud)
结果Edit类型?
这样做的原因是我绑定了EditXAML的实例,我真的不想写一个IValueConverter只是为了做到这一点.
编辑:
所以,我才意识到这些类型不适合我的XAML.相反,我得到的实例FSharp.Data.Runtime.BaseTypes.XmlElement当然甚至不包含我在F#代码中看到的属性.我还需要从C#代码中使用这些类型,甚至在那里我只得到XmlElement没有属性的s
我知道我可以在XAML中使用XPath来导航其中的XElements,但是我仍然需要一种以强类型方式访问结果对象模型的方法,包括C#和XAML.
EDIT2:
所以现在我写了一个这样的类型扩展:
type Catalog.Edit with
member this.LocalTime with get() = this.Date.ToLocalTime()
Run Code Online (Sandbox Code Playgroud)
我看到F#代码中的成员就像生成的成员一样.然而,这种方法有两个缺点:
1 - 它迫使我把我namespace改成a module,这不太方便,因为这些类型都是从C#代码中消耗掉的,在那里我把它们看作模块类的嵌套类,这很难看.
2 - 我仍然无法从C#和XAML中看到这个成员(也不是生成的成员).
在描述的场景中实现这一点的正确方法是什么?
给出以下代码:
let mapOption (f : ('a -> 'b)) (x : 'a option) =
match x with
| Some x -> Some(f(x))
| None -> None
let mapOptions (f : ('a -> 'b)) (xs : 'a option list) : 'b option list =
xs
|> List.map (fun (x : 'a option) -> mapOption f x)
let myList = [None; Some 1; Some 2; None]
let a = myList |> mapOptions (fun x -> x + 2)
let b = myList |> …Run Code Online (Sandbox Code Playgroud) 是否可以使用复杂路径从JSON获取属性,例如"prop1.prop2"?我使用的JSON示例:
{
"prop1": {
"prop2": "value"
}
}
Run Code Online (Sandbox Code Playgroud)
我想要的是"prop2"以其价值获得财产"value":当我尝试:
#r "../packages/FSharp.Data.2.3.0/lib/net40/FSharp.Data.dll"
open FSharp.Data
open FSharp.Data.JsonExtensions
let json = JsonValue.Load "SampleJson.json"
json.GetProperty("prop1.prop2")
Run Code Online (Sandbox Code Playgroud)
我有:
System.Exception: Didn't find property 'prop1.prop2' in {"prop1":{"prop2":"value"}}
Run Code Online (Sandbox Code Playgroud)
我尝试用自己的方法编写这样的方法,但看起来很笨拙:
let rec tryGetChildValue (propNameSplitted : List<string>) (json:JsonValue) =
match propNameSplitted with
| [] -> None
| [x] -> json.TryGetProperty (x)
| x::xs ->
match json.TryGetProperty (x) with
| Some p -> tryGetChildValue xs (json.GetProperty(x))
| None -> None
let tryGetPropValue (propName: string) (json:JsonValue) = …Run Code Online (Sandbox Code Playgroud) 好吧,奇怪的问题在这里。我正在使用FSharp.Data.SqlClient从我们的数据库中获取记录。它推断出的记录有几个字段,它们是选项类型。我需要过滤掉任何选项类型都为 None 的记录,并在已知字段的地方创建新记录。下面是我正在谈论的一个例子。为了解决这个问题,我创建了一个过滤器函数,recordFilter在所有类型都Option<'T>包含值的情况下返回我想要的类型,None当它们不包含时返回我想要的类型。
我的问题是是否有可能创建一个函数来自动检查Option<'T>记录中的所有字段是否有值。我猜这需要某种反射来遍历记录的字段。我猜这是不可能的,但我想把它扔掉,以防万一我错了。
如果这种方法是惯用的方式,那么我会很高兴听到这个。我只是想确保我不会错过一些更优雅的解决方案。F# 的可能性始终让我感到惊讶。
我的动机是我正在处理几十个字段的记录,这些字段的类型为Option<'T>. match...with像我在这个例子中所做的那样,不得不写出大量的语句是很烦人的。只有几个字段的时候还好,30+个字段的时候就烦了。
type OptionRecord = {
Id: int
Attr1: int option
Attr2: int option
Attr3: int option
Attr4: int option
Attr5: int option
Attr6: int option
}
type FilteredRecord = {
Id: int
Attr1: int
Attr2: int
Attr3: int
Attr4: int
Attr5: int
Attr6: int
}
let optionRecords = [for i in 1..5 ->
{
OptionRecord.Id = i
Attr1 = Some …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用来自冠状病毒大流行的实时数据(不幸的是,祝我们所有人好运)。
我开发了一个小脚本,我正在过渡到一个控制台应用程序:它使用 CSV 类型的提供程序。
我有以下问题。假设我们要按地区过滤意大利传播,我们可以将此代码用于 .fsx 文件:
open FSharp.Data
let provinceData = CsvProvider< @"https://raw.githubusercontent.com/pcm-dpc/COVID-19/master/dati-province/dpc-covid19-ita-province.csv" , IgnoreErrors = true>.GetSample()
let filterDataByProvince province =
provinceData.Rows
|> Seq.filter (fun x -> x.Sigla_provincia = province)
Run Code Online (Sandbox Code Playgroud)
由于序列懒惰,然后假设我强制编译器将罗马省的数据加载到内存中,我可以添加:
let romeProvince = filterDataByProvince "RM" |> Seq.toArray
Run Code Online (Sandbox Code Playgroud)
这工作正常,由 FSI 在本地运行。
现在,如果我使用 .fs 文件将此代码转换为控制台应用程序;我声明了完全相同的函数并使用完全相同的类型提供程序加载器;但我没有使用最后一行来收集数据,而是将其放入主函数中:
[<EntryPoint>]
let main _ =
let romeProvince = filterDataByProvince "RM" |> Seq.toArray
Console.Read() |> ignore
0
Run Code Online (Sandbox Code Playgroud)
这会导致以下运行时异常:
System.Exception
HResult=0x80131500
Message=totale_casi is missing
Source=FSharp.Data
StackTrace:
at <StartupCode$FSharp-Data>.$TextRuntime.GetNonOptionalValue@139-4.Invoke(String message)
at CoronaSchiatta.Evoluzione.provinceData@10.Invoke(Object parent, String[] row) in C:\Users\glddm\source\repos\CoronaSchiatta\CoronaSchiatta\CoronaEvolution.fs:line 10 …Run Code Online (Sandbox Code Playgroud) f# f#-interactive type-providers f#-data fsharp.data.typeproviders