Column/Validation Deedle 保证
Column/Validation guarantees with Deedle
有没有办法表达数据框已经过验证的概念?我能想到的最好方法是创建一个包装器类型来限制访问。我欢迎任何建议。
简单示例:
#r "nuget: Deedle"
open Deedle
type CustomFrame =
| Some of Frame<int,string>
| None
let map mapping option = match option with None -> None | Some x -> Some (mapping x)
let iter action option = match option with None -> () | Some x -> action x
let parse (df:Frame<_,_>) =
let keys = df.ColumnKeys |> Set.ofSeq
if keys.Contains("Entry") && keys.Contains("Color") then
df
|> Frame.indexRowsInt "Entry"
|> CustomFrame.Some
else
CustomFrame.None
let go (df:CustomFrame) =
df
|> map (Frame.filterRowsBy "Color" "Red")
let data = "Entry;Color;N\n1;Red;7\n2;Blue;42\n3;Blue;21"
let bytes = System.Text.Encoding.UTF8.GetBytes data
let stream = new MemoryStream( bytes )
Frame.ReadCsv(stream = stream,separators = ";",hasHeaders = true)
|> parse
|> go
|> iter (fun d-> d.Print())
Color N
1 -> Red 7
两条建议:
- 有
parse
return 标准 Option
值,正如 Fyodor 所建议的那样。
- Short-circuit 验证失败时的计算。换句话说,如果
parse
returns None
,根本不要调用 go
和 iter
。
如果你真的想在 parse
之后进行防御性编程,并且不需要进一步验证,你不再需要 None
值。因此,您可以使用简化的包装器类型来确保始终拥有经过验证的框架:
type ValidFrame = Valid of Frame<int,string>
let map f (Valid df) = f df |> Valid
let iter (f : _ -> unit) (Valid df) = f df
let go = map (Frame.filterRowsBy "Color" "Red")
然后像这样使用它:
Frame.ReadCsv(stream = stream,separators = ";",hasHeaders = true)
|> parse
|> Option.map (
Valid
>> go
>> iter (fun df -> df.Print()))
但是,就我个人而言,除非有令人信服的理由,否则我认为包装器类型有点矫枉过正。
有没有办法表达数据框已经过验证的概念?我能想到的最好方法是创建一个包装器类型来限制访问。我欢迎任何建议。
简单示例:
#r "nuget: Deedle"
open Deedle
type CustomFrame =
| Some of Frame<int,string>
| None
let map mapping option = match option with None -> None | Some x -> Some (mapping x)
let iter action option = match option with None -> () | Some x -> action x
let parse (df:Frame<_,_>) =
let keys = df.ColumnKeys |> Set.ofSeq
if keys.Contains("Entry") && keys.Contains("Color") then
df
|> Frame.indexRowsInt "Entry"
|> CustomFrame.Some
else
CustomFrame.None
let go (df:CustomFrame) =
df
|> map (Frame.filterRowsBy "Color" "Red")
let data = "Entry;Color;N\n1;Red;7\n2;Blue;42\n3;Blue;21"
let bytes = System.Text.Encoding.UTF8.GetBytes data
let stream = new MemoryStream( bytes )
Frame.ReadCsv(stream = stream,separators = ";",hasHeaders = true)
|> parse
|> go
|> iter (fun d-> d.Print())
Color N
1 -> Red 7
两条建议:
- 有
parse
return 标准Option
值,正如 Fyodor 所建议的那样。 - Short-circuit 验证失败时的计算。换句话说,如果
parse
returnsNone
,根本不要调用go
和iter
。
如果你真的想在 parse
之后进行防御性编程,并且不需要进一步验证,你不再需要 None
值。因此,您可以使用简化的包装器类型来确保始终拥有经过验证的框架:
type ValidFrame = Valid of Frame<int,string>
let map f (Valid df) = f df |> Valid
let iter (f : _ -> unit) (Valid df) = f df
let go = map (Frame.filterRowsBy "Color" "Red")
然后像这样使用它:
Frame.ReadCsv(stream = stream,separators = ";",hasHeaders = true)
|> parse
|> Option.map (
Valid
>> go
>> iter (fun df -> df.Print()))
但是,就我个人而言,除非有令人信服的理由,否则我认为包装器类型有点矫枉过正。