Question

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.

Was it helpful?

Solution

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). 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.

OTHER TIPS

You need to change your Report type to:

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.

You can then filter the Detail and Summary elements using List.choose e.g.

let details = reports |> List.choose (function Detail(d) -> Some(d) | _ -> None)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top