Здесь есть микро-вопрос о том, почему в последнем ответе, который я придумал, необходим повышающий отклик (внизу);и макро-вопрос о том, не скучаю ли я по «слону в комнате»: какой-то действительно очевидный лаконичный способ делать то, что я хочу [пожалуйста, не спрашивайте меня, почему я хочу то, чего хочу;просто примите это как данность, что я этого хочу, и это ...]
Я хочу инициализировать BsonDocument из F # через ассемблер MongoDB.Bson CLR.Конкретная перегрузка конструктора BsonDocument, которую я думаю, что я должен использовать, это
MongoDB.Bson.BsonDocument.BsonDocument(IDictionary<string,object>)
, и вот почему я думаю, что это тот, который я должен использовать (ниже приводится длинная прогулка по саду типов ...)
Пример C # с сайта MongoDB Учебное пособие по CSharp для MongoDB использует синтаксис инициализатора коллекции, который сопоставляется с одним или несколькими вызовами .Add на интерфейсе, предоставляемом BsonDocument.Пример учебника похож на следующий:
var bdoc = new BsonDocument { { "a", "1" }, { "b", "2" }, };
Я не уверен, какая перегрузка .Add используется (и не знаю, как проверить в Visual Studio), но все перегрузки на основе словарянапечатаны как,В этом случае вторые значения в каждой паре, а именно «1» и «2» типа string, автоматически (по наследству) также имеют тип объекта, так что все в порядке.И другие перегрузки .Add, которые требуют, чтобы второй элемент имел тип BsonValue, который является абстрактным супертипом BsonString, который имеет неявное преобразование из строки .NET независимо от используемой перегрузки;так что там тоже все нормально.Неважно, какая перегрузка конструктора вызывается.
Это немного сложно маневрировать в F # -эквиваленте, потому что трудно получить метод .Add BsonDocument.Я думал о
[("a", "1");("b", "2");] |> Seq.iter BsonDocument.Add
, но это не работает, потому что BsonDocument.Add не является статическим методом;Я мог бы создать экземпляр BsonDocument, а затем написать забавную лямбду, которая вызывает метод BsonDocument .Add, который, по крайней мере, изолировал бы изменчивость от удовольствия:
[("a", "1");("b", "2");] |> Seq.fold ...
, но это оказалось очень уродливо, так какшутка, требующая явной записи типа в BsonDocument, потому что переменная, ссылающаяся на BsonDocument, происходит до (new BsonDocument ()), поэтому вывод типа слева направо не имеет достаточно информации (пока), а также потому, что шутка (по крайней мере, по-видимому) не может знать, что он должен получить доступ к неявному преобразованию из строки в BsonString для второго значения в каждой паре ...
let bdoc = [("a","1");("b","2");] |> Seq.fold (fun (doc:BsonDocument) pair -> doc.Add(fst pair, new BsonString(snd pair))) (new BsonDocument())
... независимо от того, подумал я, яЯ буду использовать большую перегрузку конструктора
BsonDocument(IDictionary<string, object>)
, но это будет вынуждено сделать следующее:
let bdoc = (new BsonDocument(dict
[("a", "1" :> Object);
("b", "2" :> Object);
]))
Если я уберу апкасты
:> Object
затем F # жалуется, что не может найти перегрузку BsonDocument.
(длинная прогулка по саду окончена ...)
После всего этого возникает микро вопрос, почему в F # нельзя выяснить, что "1" и "2"во входном словаре есть объекты и, таким образом, они находят соответствующую перегрузку?
И вопрос макроса с большей картинкой состоит в том, пропустил ли я только что подходящий, передовой метод, суперохлаждение, лаконичный способ сделать это в F #