Список типов объединения F#

Мне нужен список отчетов. Отчет может быть типа «Подробно» или «Раздел».

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

Затем в моем коде я хотел бы сделать следующее:

let mutable (reports:Report list) = []

...

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

Компилятор жалуется в первом случае: "Выражение должно было иметь тип Report, а здесь тип Detail", и, соответственно, аналогично во втором случае.

Я сошел с ума, если хочу сделать такую ​​вещь? Должен ли я думать о проблеме по-другому? Поскольку отчет является либо подробным, либо сводным, не должен ли список отчетов принимать либо детали, либо сводку? Что такое список отчетов, если не список деталей или сводок?

Спасибо.


person Jeff Maner    schedule 07.12.2012    source источник


Ответы (2)


У вас просто немного неправильный синтаксис:

type Report = Detail of Detail | Summary of Summary

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

В своем коде вы в основном только что определили тип Report как перечисление с двумя возможными значениями Details или Summary (в этом контексте это похоже на метки, а не на типы разных подтипов). Размеченные объединения в F# явно помечены тегами, поэтому вам также нужно использовать один из конструкторов объединения, чтобы создать экземпляр для помещения в список.

person kvb    schedule 07.12.2012

Вам нужно изменить тип Report на:

type Report = Detail of Detail | Summary of Summary

поскольку ваше текущее определение просто называет два случая вашего типа отчета, и эти имена не связаны с существующими типами Detail и Summary.

Затем вы можете отфильтровать элементы Detail и Summary, используя List.choose, например.

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