我无法理解(例如)eol
的类型是什么意思:
eol :: (MonadParsec e s m, Token s ~ Char) => m String
或者,更好的是,我不明白如何在Text.Megaparsec.Text
而不是Text.Megaparsec.String
中使用eol。
我一直在尝试使用学习如何使用Megaparsec跟随来自Real World Haskell的Parsec的(旧)教程(我实际上在发现Megaparsec存在之前就开始阅读RWH教程)。我重写了code of the first example以使用Megaparsec(见下文)。但我发现当我尝试将eol
的类型强制为Parser Text
时,编译器会抛出错误:Couldn't match type ‘[Char]’ with ‘Text’
,我从中收集到的是我无法使用eol
使用Text
,或者更有可能的是,我不知道如何从Token s ~ Char
声明中更改eol
上下文以使用Token Text
。
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoImplicitPrelude #-}
module CSVParser (
module CSVParser
) where
import Foundation
import Data.Functor.Identity (Identity)
import Text.Megaparsec
import Text.Megaparsec.Text
import Data.Text
csvFile :: Parser [[Text]]
csvFile =
do result <- many line
eof
return result
line :: Parser [Text]
line =
do result <- cells
--eol :: Parser Text -- uncommenting this line results in a compilation error
eol
return result
cells :: Parser [Text]
cells =
do first <- cellContent
next <- remainingCells
return (first : next)
remainingCells =
(char ',' >> cells)
<|> return []
cellContent :: Parser Text
cellContent = fromList <$> many (noneOf [',','\n'])
parseCSV :: Text -> Either (ParseError (Token Text) Dec) [[Text]]
parseCSV = parse csvFile "(unknown)"
答案 0 :(得分:4)
在类型中:
eol :: (MonadParsec e s m, Token s ~ Char) => m String
~
是类型相等约束,MonadParsec
和Token
类型类由Megaparsec定义。它们大致可以解释如下:
MonadParsec e s m
是一个断言,类型m
是一个monadic解析器,它读取Stream
类型s
并使用类型ErrorComponent
表示错误{1}} e
是从流Token s
因此,完整类型可以解释为:s
是一个具有“返回值”eol
的monadic解析器,用于解析其标记为String
的流。
对于您的问题,大部分内容都可以忽略。您遇到的问题是,Char
作为解析结果返回eol
值,而String
不是String
,因此您可以' t Text
eol
类型Parser String
类型Parser Text
,无论你怎么努力。
两种解决方案是忽略不需要的String
返回值,或者,如果您需要它作为文本,请将其转换为:
Data.Text.pack <$> eol