Невозможно преобразовать значение типа Parser 'закрыть тип результата' Parser <_, [_]> ' - PullRequest
0 голосов
/ 14 января 2020

Я нашел этот простой комбинатор парсера на github, но он был написан на Swift 2, поэтому он не работает вообще с новыми версиями Swift. Мне удалось перенести почти все это на рабочий код Swift 5, но у меня возникла проблема с этим одним комбинатором, которую я не могу понять.

У меня есть этот комбинатор manyTill, который соответствует парсеру p до совпадения с другим парсером end. Он определяется следующим образом:

public func manyTill<In, Out, Out2>(
  _ p: Parser<In, Out>,
  _ end: Parser<In, Out2>
) -> Parser<In, [Out]> {
  fix { (f: @escaping () -> Parser<In, [Out]>) -> () -> Parser<In, [Out]> in
    { () -> Parser<In, [Out]> in
      (end *> pure(Array<Out>())) <|> (cons <^> p <*> f())
    }
  }()
}

Возвращает новый Parser с типом вывода [Out], где Out - это тип вывода синтаксического анализатора p. Он рекурсивно сопоставляет синтаксический анализатор p с использованием функции fix, которая является комбинатором с фиксированной запятой, определяемым как:

internal func fix<T, U>(_ f: @escaping (@escaping (T) -> U) -> (T) -> U) -> (T) -> U {
  { f(fix(f))($0) }
}

Комбинатор также использует ряд пользовательских операторов: <*> применяет один парсер к другой, *> делает то же самое, но игнорирует выходные данные парсера 1, <^> применяет функцию к парсеру (например, flatMap), а <|> соответствует парсеру 1 или 2. Я уверен, что операторы все определены правильно, так как у меня нет других проблем в моем коде, кроме этого внутреннего замыкания. Я также проверил, что выражение (end *> pure(Array<Out>())) <|> (cons <^> p <*> f()) действительно возвращает тип Parser<In, [Out]>.

. При построении проекта в операторе <|> выделяется следующая ошибка:

Cannot convert value of type 'Parser<In, [Out]>' to closure result type 'Parser<_, [_]>'

Как вы можете видеть в примере кода, я добавил явные типы для обоих замыканий. Закрытие, переданное в fix, должно иметь явную подпись, в противном случае я получаю больше ошибок, связанных с неправильным выводом типа параметра f. При удалении явного типа в самом внутреннем замыкании сообщение об ошибке меняется на:

Cannot convert value of type 'Parser<In, [Out]>' to closure result type 'Parser<In, Out>'

Я не могу понять, почему ожидается, что тип результата замыкания будет Parser<_, [_]> или Parser<In, Out>, несмотря на наличие явных типов для всего , Я не могу понять, что я делаю неправильно, поэтому, надеюсь, кто-то еще сможет определить, что с ним не так.

Если это поможет, вы можете найти исходный код исходной функции на GitHub .

...