Проблема в том, что space
анализатор в следующей строке:
inputPara = Prose <$> many1' (letter <|> digit <|> space <|> satisfy (inClass specialChars) <|> satisfy (inClass "――.?!") )
соответствует символам, таким как \n\r\t
(каждый символ, который isSpace
)
Именно поэтому inputPara
соответствует всему тексту без разделения.
Одним из решений может быть удаление парсера space
из inputPara
и добавление символа ' '
в specialChars
Например, следующий код должен работать, но, безусловно, не стесняйтесь выбирать вариант, который подходит вам лучше всего:
import Data.Attoparsec.Text
import qualified Data.Text as T
import qualified Data.Text.IO as Txt
import Control.Applicative ((<|>))
newtype Prose = Prose {
word :: [Char]
}
instance Show Prose where
show a = word a
optional :: Parser a -> Parser ()
optional p = option () (try p *> pure ())
specialChars = ['-', '_', '…', '“', '”', '\"', '\'', '’', '@', '#', '$',
'%', '^', '&', '*', '(', ')', '+', '=', '~', '`', '{', '}',
'[', ']', '/', ':', ';', ',', ' ']
inputPara :: Parser Prose
inputPara = Prose <$> many1' (letter <|> digit <|> satisfy (inClass specialChars) <|> satisfy (inClass "――.?!") )
paraSeparator :: Parser [Char]
paraSeparator = many1 space
paraParser :: String -> [Prose]
paraParser str = case parseOnly wp (T.pack str) of
Left err -> error err
Right x -> x
where
wp = optional paraSeparator *> inputPara `sepBy1` paraSeparator
main :: IO()
main = do
input <- readFile "test.txt"
let para = paraParser input
print para
print $ length para