Вообще говоря, я думаю, что типы шляп, такие как ^x
, возможно, используются слишком часто (по крайней мере, судя по количеству вопросов о них в SO). Это мощная функция, но она действительно была разработана главным образом для решения проблем с общей арифметикой. Я думаю, что они могут сделать программы на F # излишне сложными.
Если вы работаете только с XDocument
и XElement
, то ответ довольно прост, потому что вы можете использовать XContainer
, который является их общим базовым классом и имеет метод Descendants
:
let descendants name (xml:XContainer) = xml.Descendants(name)
// Both of these will work fine
descendants (XName.Get "foo") xd
descendants (XName.Get "foo") xe
Если вы не можете найти общий базовый класс, тогда вы, конечно, можете использовать тип ^a
, но вы также можете использовать обычную перегрузку, которая возможна в F #, но работает только для членов типа объекта:
type Xml =
static member Descendants(name, x:XDocument) = x.Descendants(name)
static member Descendants(name, x:SomeOtherClass) = x.SomeOtherDescendants(name)
// The usage looks like this:
Xml.Descendants(XName.Get "foo", xd)
Xml.Descendants(XName.Get "foo", new SomeOtherClass())
(Поскольку вы сослались на вопрос с ответом, который уже показывает, что перегрузка работает с участниками, это, вероятно, не является чем-то новым для вас. Но это может быть полезно для тех, кто найдет этот вопрос в будущем). 1015 *