Ошибка разбора символа (――) в Haskell

Я пишу синтаксический анализатор для анализа огромных кусков английского текста с помощью attoparsec. До сих пор все было отлично, за исключением разбора этого символа "――". Я знаю, что это всего лишь два тире вместе "--". Странно то, что синтаксический анализатор ловит это в этом коде:

wordSeparator :: Parser ()
wordSeparator = many1 (space <|> satisfy (inClass "――?!,:")) >> pure () 

но не в этом случае:

specialChars = ['――', '?', '!', ',', ':']
wordSeparator :: Parser ()
wordSeparator = many1 (space <|> satisfy (inClass specialChars)) >> pure ()

Причина, по которой я использую список specialChars, заключается в том, что мне нужно рассмотреть множество символов, и я применяю его во многих случаях. И для ввода рассмотрим: "I am ――Walt Whitman._" и вывод должен быть {"I", "am", "Walt", "Whiteman."} Я считаю, что это в основном потому, что "――" не является Char? Как это исправить?


person centrinok    schedule 06.05.2018    source источник


Ответы (1)


Char — это один символ, точка. ―― — это два символа, поэтому это два Char. Вы можете вместить столько Char, сколько захотите, в String, но вы, конечно, не сможете вместить две Char в одну Char.

Поскольку satisfy рассматривает отдельные символы за раз, это, вероятно, не то, что вам нужно, если вам нужно проанализировать последовательность из двух символов как единое целое. Функция inClass просто создает предикат для символов (частичное применение inClass к одному аргументу дает функцию типа Char -> Bool), так что inClass "――" совпадает с inClass ['―', '―'], который точно такой же, как inClass ['―'], поскольку дубликаты не имеют значения. Это вам мало поможет.

Рассмотрите возможность использования string вместо inClass или в сочетании с ним, так как он предназначен для обработки последовательностей символов. Например, что-то вроде этого может лучше соответствовать вашим потребностям:

wordSeparator :: Parser ()
wordSeparator = many1 (space <|> string "――" <|> satisfy (inClass "?!,:")) >> pure ()
person Alexis King    schedule 06.05.2018
comment
Извините, я должен был указать, что я использовал Data.Text и использовал строку - это вызвало бы ошибку. Но, тем не менее, я исправил это, используя другой inClass. Вы можете увидеть мой обновленный пост. - person centrinok; 06.05.2018
comment
Спасибо за предложение, так и сделаю. Но просто из чистого любопытства, какие последствия/последствия были бы, если бы я использовал еще одно удовлетворение (inclass --) ? - person centrinok; 06.05.2018
comment
@ceeks Как я уже упоминал в своем ответе, inClass "――" будет точно эквивалентно inClass ['―'], поэтому ваш анализатор будет обрабатывать строку ―― как два разных разделителя, а один будет анализировать как разделитель. Я предполагаю, что это не то, что вам нужно, потому что если бы это было так, вы бы просто написали inClass "―" и покончили с этим. - person Alexis King; 06.05.2018