Я нашел этот простой комбинатор парсера на 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 .