【问题标题】:F# Type Inference Odd Behavior With Records记录的 F# 类型推理奇怪行为
【发布时间】:2017-07-29 21:00:34
【问题描述】:

我正在学习 F#,我试图弄清楚为什么当我用正确的类型覆盖推断的类型时,它会用 List.Filter 推断出不同的类型。代码值一千字:

type Account = 
{ account : int
  label : string }

type Journal = 
{ account : int
  period : string
  debit : int
  credit : int }

let outputJournal (journals: Journal List) (account:Account) =
    let filtered = List.filter (fun x -> x.account = account.account) journals
    filtered

我需要根据指定的帐户过滤期刊列表。但是,outputJournal 函数在传递给List.filterjournals 参数下输出错误。错误如下:“类型不匹配。应为'Account list'但给定'List Journal'。'Account'类型与'Journal'类型不匹配”。

我很困惑为什么会这样,因为我(或者我认为)清楚地试图过滤期刊列表。有没有一种方法可以覆盖类型推断以执行我的意思或以其他方式使编译器更清楚我的意图(重命名任一记录中的帐户字段是一种选择,但我想避免它)?

非常感谢。谢谢。

【问题讨论】:

  • 类型推断是从左到右的。注释x的类型
  • @JohnPalmer 非常感谢!将来知道这将非常有帮助。
  • 你也可以把journals放在List.filter之前,如journals |> List.filter (fun ...

标签: f# type-inference


【解决方案1】:

F# 中的类型推断严格按照从上到下、从左到右的方式进行。

因此,当您执行 x.account 时,编译器会猜测 xAccount,因此您会收到错误消息。

要解决这个问题,你可以做两件事

1) 标注x的类型

let filtered = List.filter (fun (x:Journal) -> x.account = account.account) journals

2) 使用管道运算符更改顺序(感谢 Fyodor)

let filtered = journals |> List.filter (fun x -> x.account = account.account) 

由于类型推断的工作方式,(2)更常见

【讨论】:

  • ...而且因为它看起来更干净。
猜你喜欢
  • 1970-01-01
  • 2016-02-29
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 1970-01-01
相关资源
最近更新 更多