Как добавить элемент во вложенный массив - PullRequest
0 голосов
/ 12 апреля 2019

Когда я пытаюсь добавить элемент в список, подобный этому:

open MongoDB.Driver

type SegmentId = string

type SegmentRM =
    { id : SegmentId      
      users: string list }

let addUserToSegment (collection : IMongoCollection<SegmentRM>) (id: SegmentId) (usr: string) =
    let filter = Builders.Filter.Eq((fun x -> x.id), id)
    let update = Builders.Update.Push<string>((fun x -> x.users), usr)
    collection.UpdateOneAsync(filter, update)

У меня ошибка компиляции No overloads match for method 'Push'. The available overloads are shown below. А также пробовал с users: string[] с такой же ошибкой. Кто-нибудь знает, как избежать этой ошибки компиляции?

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

Предполагая, что вы вызываете этот Builders.Update.Push метод, вам придется явно привести или преобразовать список в последовательность, либо напрямую, либо вызвав Seq.ofList , которыйделает это так:

[<CompiledName("OfList")>]
let ofList (source : 'T list) =
    (source :> seq<'T>)

Обычный и гораздо более читаемый способ - использовать Seq.ofList, поэтому вы должны использовать:

let update = Builders.Update.Push<string>((fun x -> x.users |> Seq.ofList), usr)

Объяснение

Причина этого в том, что Push ожидает функцию, которая возвращает IEnumerable<T>.Его синтаксис:

static member Push : 
    memberExpression : Expression<Func<'TDocument, IEnumerable<'TValue>>> * 
    value : 'TValue -> UpdateBuilder<'TDocument> 

Список реализует интерфейс IEnumerable<T> :

type List<'T> = 
   | ([])  :                  'T list
   | (::)  : Head: 'T * Tail: 'T list -> 'T list
   interface System.Collections.Generic.IEnumerable<'T>
   ...

Компилятор F # не может неявно приводиться к интерфейсу вдело вопроса хотя.

A seq с другой стороны - это псевдоним типа для IEnumerable<T>:

type seq<'T> = IEnumerable<'T> 

Seq.ofList приведёт список users кIEnumerable<string>, что Push ожидает

1 голос
/ 12 апреля 2019

Ошибка компилятора говорит о том, что string list несовместимо с IEnumerable<string>.Однако string seq означает, что вы должны определить свой тип следующим образом

type SegmentRM =
    { id : SegmentId      
      users: string seq }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...