Haskell megaparsec:如何声明'eol'的类型来解析文本而不是[Char]
我不明白(例如)的类型是什么意思: 或者,更好的是,我不知道如何将eol与Haskell megaparsec:如何声明'eol'的类型来解析文本而不是[Char],haskell,types,megaparsec,Haskell,Types,Megaparsec,我不明白(例如)的类型是什么意思: 或者,更好的是,我不知道如何将eol与Text.Megaparsec.Text一起使用,而不是Text.Megaparsec.String 我一直在努力学习如何使用Megaparsec,遵循真实世界Haskell的(旧)Parsec教程(实际上,在发现Megaparsec存在之前,我首先开始阅读RWH教程)。我重写了,以使用Megaparsec(见下文)。但我发现,当我试图将eol类型强制为Parser Text时,编译器抛出错误:无法将类型“[Char]”与
Text.Megaparsec.Text
一起使用,而不是Text.Megaparsec.String
我一直在努力学习如何使用Megaparsec,遵循真实世界Haskell的(旧)Parsec教程(实际上,在发现Megaparsec存在之前,我首先开始阅读RWH教程)。我重写了,以使用Megaparsec(见下文)。但我发现,当我试图将eol
类型强制为Parser Text
时,编译器抛出错误:无法将类型“[Char]”与“Text”
匹配,我从中得出的结论是,我无法将eol
与Text
一起使用,或者更可能,我不知道如何将tokens~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)"
{-#语言重载字符串}
{-#语言无mplicitprelude}
CSVParser模块(
CSVParser模块
)在哪里
进口基金会
导入Data.Functor.Identity(Identity)
导入文本.Megaparsec
导入Text.Megaparsec.Text
导入数据.Text
csvFile::解析器[[Text]]
CSV文件=
在类型中执行结果:
eol :: (MonadParsec e s m, Token s ~ Char) => m String
~
是类型相等约束,而MonadParsec
和Token
类型类由Megaparsec定义。它们可以大致解释如下:
MonadParsec e s m
是一个断言,类型m
是一个一元解析器,它读取类型s
的流
,并使用类型e
的错误组件
表示错误
tokens
是从流s
因此,完整类型可以解释为:eol
是一个具有“返回值”String
的一元解析器,它解析一个标记为Char
的流
对于你的问题,大部分都可以忽略。您遇到的问题是,eol
返回一个字符串
值作为解析结果,而字符串
不是文本
,因此无论您如何努力,都无法将eol
(类型为解析器字符串
)设置为解析器文本
两种解决方案是忽略不需要的字符串
返回值,或者,如果需要将其转换为文本,则将其转换为:
Data.Text.pack <$> eol
Data.Text.pack下线
在类型中:
eol :: (MonadParsec e s m, Token s ~ Char) => m String
~
是类型相等约束,而MonadParsec
和Token
类型类由Megaparsec定义。它们可以大致解释如下:
MonadParsec e s m
是一个断言,类型m
是一个一元解析器,它读取类型s
的流
,并使用类型e
的错误组件
表示错误
tokens
是从流s
因此,完整类型可以解释为:eol
是一个具有“返回值”String
的一元解析器,它解析一个标记为Char
的流
对于你的问题,大部分都可以忽略。您遇到的问题是,eol
返回一个字符串
值作为解析结果,而字符串
不是文本
,因此无论您如何努力,都无法将eol
(类型为解析器字符串
)设置为解析器文本
两种解决方案是忽略不需要的字符串
返回值,或者,如果需要将其转换为文本,则将其转换为:
Data.Text.pack <$> eol
Data.Text.pack下线
当忽略其返回值时,为什么要编写eol::Parser Text
?我之所以这样做是因为我想知道如何更改其类型。我想更改它的类型,因为库中的许多其他函数都有相同的类型声明,例如lowerChar::(MonadParsec e s m,Token s~Char)=>m Char
,我可能不想忽略它的返回值,而是将它约束为“Text”(为此,我可以从列表lowerChar中执行,但这看起来很难看,我想我可以直接更改类型,但我不知道或不理解如何更改)。我的问题主要是(MonadParsec s m,Token s~Char)=>m Char
。当忽略其返回值时,为什么要编写eol::Parser Text
?我这样做是因为我想知道如何更改其类型。我想更改其类型是因为库中的许多其他函数都具有相同的类型声明,例如lowerChar::(MonadParsec e s m,Token s~Char)=>m Char
,我可能不想忽略它的返回值,而是将它约束为“Text”(因为我可以从List lowerChar中执行,但这看起来很难看,我想我可以直接更改类型,但我不知道或不理解如何更改)。我的问题主要是(MonadParsec e s m,Token s~Char)=>m Char
。感谢您对~
的解释,它确实帮助了我。我认为类型Parsec Dec Text
(在导入Megaparsec.Text
时以Parser
编写)将eol
的输出调节为Text
,而实际上它只强制Text
作为eol
的输入流,因此在我的(code)示例中eol
的类型是Parsec Dec Text[Char]
。但是我想得到Parsec Dec Text Text
,这显然是不可能的!因为eol
的类型(约束)=>m[Char]==Parsec e s[Char]
。顺便说一句,我还学到了令牌Text==Char
,这是我没有想到的!因为我看到Text
和[Char
是不同的东西(它们是,[Char]