Пожалуйста, посмотрите ниже, как MCVE может выглядеть в вашем случае, для fsx-файла вы можете ссылаться на Fsharp.Data
dll с #r
, для скомпилированного проекта просто ссылаться на dll и открывать его.
#if INTERACTIVE
#r @"..\..\SO2018\packages\FSharp.Data\lib\net45\FSharp.Data.dll"
#endif
open FSharp.Data
[<Literal>]
let datafile = @"C:\tmp\data.csv"
type CsvFile = CsvProvider<datafile>
let data = CsvFile.GetSample().Rows
В конце концов, это то, чего вы хотите достичь:
data
|> Seq.filter (fun x -> x.Id <> 15)
|> Seq.filter (fun x -> x.Id <> 40)
//val it : seq<CsvProvider<...>.Row> = seq [(48, "MO"); (78, "TN"); (41, "VT")]
Один из способов сделать это - SRTP , так как они позволяютделать структурную типизацию, где тип зависит от его формы, например, в этом случае, имеющей свойство Id
.Если вы хотите, вы можете определить вспомогательную функцию для двух чисел 15 и 40 и использовать ее в своем фильтре, как во втором примере.Однако синтаксис SRTP немного странный, и он разработан для случая использования, когда вам нужно применить функцию к различным типам, которые имеют некоторое сходство (в основном, как интерфейсы).
let inline getId row =
(^T : (member Id : int) row)
data
|> Seq.filter (fun x -> (getId x <> 15 ))
|> Seq.filter (fun x -> (getId x <> 40))
//val it : seq<CsvProvider<...>.Row> = seq [(48, "MO"); (78, "TN"); (41, "VT")]
Теперь вернемся к исходному сообщению, как вы правильно указали, ваша функция будет отображать ошибку, поскольку вы определяете ее как универсальную, но она должна работать с конкретным типом строки Csv (которая имеет свойство Id).Это очень легко исправить, просто добавьте аннотацию типа к параметру row
.В этом случае ваш тип CsvFile.Row
, и, поскольку CsvFile.Row имеет свойство Id, мы можем получить к нему доступ в функции.Теперь эта функция возвращает логическое значение.Вы также можете сделать так, чтобы он возвращал фактическую строку.
let nullid (row: CsvFile.Row) =
row.Id = 15
let otherid (row: CsvFile.Row) =
row.Id = 40
Тогда осталось применить это внутри Seq.filter
и отрицать его:
let iddata =
data
|> Seq.filter (not << nullid)
|> Seq.filter (not << otherid)
|> Seq.toList
//val iddata : CsvProvider<...>.Row list = [(48, "MO"); (78, "TN"); (41, "VT")]