Допустим, у меня есть значительная иерархия классов:
Tag
ControlFlowTag
IfTag
ForTag
JumpTag
HTMLTag
DivTag
, и я хочу составить список из этих строк и строк.это
type Node =
| Tag of Tag
| String of String
let MyList: list<Node> = [tagA, tagB, "some text", tagC]
но, увы, он не работает без
let MyList: list<Node> = [Tag tagA, Tag tagB, String "some text", Tag tagC]
Очевидно, что тег и строка, описанные в узле, являются ортогональными и отделены от существующих классов тегов / строк.При наведении мыши на меня выводятся типы Node.Tag
и Node.String
, а это не то, что я хочу.
Теперь у меня есть функция t
, которая создает StringTag
, которая наследуется от Tag
, давая мне
let MyList : list<Tag> = [tagA, tagB, t"some text", tagC]
, что довольно приятно, но дополнительные t
добавляют визуальный шум.На самом деле мне нужен строго типизированный «список двух разных типов», с которым я мог бы работать, используя операторы match
.Я думал, что в этом и заключается смысл дискриминированных союзов, но их неспособность использовать существующие иерархии типов является проблемой, поскольку существующая иерархия (в данном случае Tag
) достаточно сложна, я думаю, что подход полного OO-наследования для этого подмножества типовэто яснее, чем чистый подход Дискриминационного союза
Один из вариантов - просто составить список из obj
и разыграть все до / во время match
, но это не очень хорошо.Есть ли другие подходы?