【问题标题】:Dealing with records处理记录
【发布时间】:2018-06-17 03:08:31
【问题描述】:

我需要从记录中提取状态的字符串版本。代码如下:

type State = State of string

type Data = 
   { State : State
     Year : int
     Income : float }

我需要做的是提取每个状态的字符串版本序列,而不是状态“字符串”。当我尝试执行以下操作时,我得到一个空序列。在运行处理数据并将数据映射到上述记录的代码后,我运行下面的代码。

let states (row:Data) = row.State
// <fun:it@145-1> val it : unit = ()

我需要一个序列,因为最后我将使用它来检查并确保一个数据集中的状态在另一个数据集中。

已编辑:

在做了类似下面的事情之后,我仍然得到空序列。

let stateToStr (State s) = s
let statec (row:StateCsv) = (stateToStr row.State)
printfn "%A" statec
// val stateToStr : State -> string
// val statec : row:StateCsv -> string
// val it : unit = ()

在将数据映射到这样的记录之后再次:

let statepa () =
  Stat.GetSample().Rows
  |> Seq.map(fun row ->  
    { State = row.STATE 
      Year  = row.Year })

【问题讨论】:

  • 当你说“我得到一个空序列”时,你的意思是你显示的输出中的() 吗?因为() 不是 一个空序列。 () 是一个称为“unit”的特殊值,它是由没有任何有意义的返回值的函数返回的值(例如 printfn,它只将内容打印到屏幕上,不返回任何内容)。阅读更多关于它的信息herehere(请注意,第一个链接是关于 Elm 的问题,但 F# 的 unit 与 Elm 的 unit 相同)。
  • 另外,当您执行printfn "%A" statec 时,您希望它做什么?因为它实际上会打印函数本身,这很少有用。我认为你的意思是printfn "%A" (statec someRow),它会将一行数据作为输入传递给函数,并打印函数的result

标签: f#


【解决方案1】:

一般来说,您可以通过模式匹配“解开”单大小写区分联合(如您的 State 类型):

let ma = State "MA"
let (State str) = ma
printfn "%s" str   // prints "MA"

或者,您可以将模式放在函数的参数中:

let stateToStr (State s) = s
printfn "%s" (stateToStr ma)   // prints "MA"

或者,如果您只需要在 states 函数中执行此操作一次,则可以将 State 模式嵌套在 Data 模式中:

let states { State = State s } = s

let row = { State = State "MA"; Year = 1; Income = 2. }
printfn "%s" (states row)   // Prints "MA"

模式可以嵌套,这是它们的强大功能。
这个特定的模式由两个嵌套模式组成:模式{ State = x }x 绑定到传入记录的字段State 的值,而模式State ss 绑定到State 的“内部值”。

【讨论】:

  • 我真的不能说什么,因为我不知道StateCsv 是什么。另外,你为什么要打印一个函数?
  • 然后作为一个单独的问题提出,@FyodorSoikin 已经回答了当前关于“处理记录”的问题。
猜你喜欢
  • 1970-01-01
  • 2016-04-28
  • 2017-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-12
  • 1970-01-01
相关资源
最近更新 更多