2016-08-04 6 views
1

Скажем, у меня есть парсер attoparsec, x.Преобразовать парсер attoparsec в парсер, который терпит неудачу, если количество байтов, которое он потребляет, не имеет определенной длины

Ищу создать функцию f :: Int -> Parser a -> Parser a, такой, что если y = f n x, то:

  • y терпит неудачу, если x не удается
  • y терпит неудачу, если x успешно и x не потребляет n байт
  • y не соответствует действительности

Как мне это сделать?

ответ

5

Вы можете использовать match для его реализации:

f n x = do 
    (bs, res) <- match x 
    guard (BS.length bs >= n) 
    return res 

Вы должны проверить, что это взаимодействует с (<|>) приемлемым способом, прежде чем положить его интенсивное использование.

+0

В 'binary' эта функция упакована как' isolate'. Возможно, это более разумно, так как «бинарный» отслеживает количество потребляемых байтов, но он поражает меня как хорошее дополнение к API attoparsec (в терминах токенов, а не байтов, поэтому Text не будет считать байты, например). –