简体   繁体   English

联盟类型的F#列表

[英]F# List of Union Types

I want a list of Reports. 我想要一份报告清单。 Report can be either Detail or Section types. 报告可以是详细信息或部分类型。

module Data

type Section = { Header: string;
                 Lines:  string list;
                 Total:  string }

type Detail = { State:     string;
                Divisions: string list;
                Sections:  Section list }

type Summary = { State:    string;
                 Office:   string;
                 Sections: Section list }

type Report = Detail | Summary

Then in my code, I'd like to do the following: 然后在我的代码中,我想做以下事情:

let mutable (reports:Report list) = []

...

reports <- detail::reports
// or
reports <- summary::reports

The compiler complains in the first case: "The expression was expected to have type Report but here has type Detail", and appropriately similarly in the second case. 编译器在第一种情况下抱怨:“表达式应该具有类型报告但这里有类型详细信息”,并且在第二种情况下适当地类似。

Am I out of my mind for wanting to do such a thing? 我不想做这样的事情吗? Should I be thinking about the problem differently? 我应该以不同的方式思考问题吗? Because Report is either Detail or Summary, shouldn't a list of Report accept either a Detail or a Summary? 由于报表是详细信息或摘要,因此报表列表不应接受详细信息或摘要? What is a Report list if not a list of Detail or Summary? 什么是报告列表,如果不是详细信息或摘要列表?

Thanks. 谢谢。

You've just got your syntax a bit wrong: 你的语法有点错误:

type Report = Detail of Detail | Summary of Summary

reports <- (Detail detail)::reports
// or
reports <- (Summary summary)::reports

In your code you've basically just defined the Report type to be an enum with the two possible values Details or Summary (these are like labels, not the types of different subtypes in this context). 在您的代码中,您基本上只是将Report类型定义为具有两个可能值的DetailsSummary的枚举(这些值类似于标签,而不是此上下文中不同子类型的类型)。 Discriminated unions in F# are explicitly tagged, so you've also got to use one of the union constructors to create an instance to put into the list. F#中的歧视联合会被明确标记,因此您还必须使用其中一个联合构造函数来创建要放入列表的实例。

You need to change your Report type to: 您需要将Report类型更改为:

type Report = Detail of Detail | Summary of Summary

since your current definition just names the two cases of your Report type, and these names are not related to the existing Detail and Summary types. 由于您当前的定义只是为您的报告类型命名两个案例,因此这些名称与现有的DetailSummary类型无关。

You can then filter the Detail and Summary elements using List.choose eg 然后,您可以使用List.choose过滤DetailSummary元素,例如

let details = reports |> List.choose (function Detail(d) -> Some(d) | _ -> None)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM