我正在试着学习如何使用attoparsec。我正在尝试解析以下格式的文本文件:
id int
call_uuid string 30我的代码如下:
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative ((<$>))
import Data.Char (isDigit, isAlpha)
import Data.Attoparsec.Text (Parser, many1, letter, many', char, digit, string,
(.*>), skipSpace, peekChar, decimal,
isHorizontalSpace, skipWhile, parseOnly)
import qualified Data.Text.IO as T
schema :: Parser [(String, String, Maybe Int)]
schema = many1 typelines
where
colname = do
c <- letter
cs <- takeWhile (\x -> isDigit x || isAlpha x || x == '_')
return (c:cs)
int :: (Integral a, Read a) => Parser a
int = read <$> decimal
typelines = do
cname <- colname
skipWhile isHorizontalSpace
tname <- takeWhile isAlpha
skipWhile isHorizontalSpace
c <- peekChar
if c == '\n'
then do { char '\n'; return (cname, tname, Nothing);}
else do
num <- int
char '\n'
return (cname, tname, num)
readDBTypes :: String -> IO [(String, String, Maybe Int)]
readDBTypes filename = do
content <- T.readFile filename
case (parseOnly schema content) of
Left err -> do
print err
return []
Right v -> return v
main :: IO ()
main = do
myLines <- readDBTypes "schema2.out"
mapM_ print myLines当我运行时,我得到以下编译器错误(ghc 7.4)
$ runhaskell schema.hs
schema.hs:18:13:
Couldn't match expected type `attoparsec-0.10.4.0:Data.Attoparsec.Internal.Types.Parser
Data.Text.Internal.Text t0'
with actual type `[a0] -> [a0]'
In the return type of a call of `takeWhile'
Probable cause: `takeWhile' is applied to too few arguments
In a stmt of a 'do' block:
cs <- takeWhile (\ x -> isDigit x || isAlpha x || x == '_')
In the expression:
do { c <- letter;
cs <- takeWhile (\ x -> isDigit x || isAlpha x || x == '_');
return (c : cs) }
schema.hs:22:20:
Could not deduce (Integral String) arising from a use of `decimal'
from the context (Integral a, Read a)
bound by the type signature for
int :: (Integral a, Read a) => Parser a
at schema.hs:22:5-26
Possible fix:
add (Integral String) to the context of
the type signature for int :: (Integral a, Read a) => Parser a
or add an instance declaration for (Integral String)
In the second argument of `(<$>)', namely `decimal'
In the expression: read <$> decimal
In an equation for `int': int = read <$> decimal
schema.hs:27:16:
Couldn't match expected type `attoparsec-0.10.4.0:Data.Attoparsec.Internal.Types.Parser
Data.Text.Internal.Text t0'
with actual type `[a0] -> [a0]'
In the return type of a call of `takeWhile'
Probable cause: `takeWhile' is applied to too few arguments
In a stmt of a 'do' block: tname <- takeWhile isAlpha
In the expression:
do { cname <- colname;
skipWhile isHorizontalSpace;
tname <- takeWhile isAlpha;
skipWhile isHorizontalSpace;
.... }我不确定这是与我的安装中损坏的包有关,还是我对类型不了解。提前感谢!
发布于 2013-06-15 07:41:52
这里有2个错误,首先在前言中takeWhile被定义为(a -> Bool) -> [a] -> [a]。您可能需要来自Data.Auttoparsec.Text的takeWhile,但您必须首先导入该文件并隐藏前置版本。
import Prelude hiding (takeWhile)
import Data.Attoparsec.Text (takeWhile)但如果这段代码变得更大,我建议
import qualified Data.AttoParsec.Text (takeWhile) as AP然后只使用AP.takeWhile,因为它更具可读性,因为当您不必到处查看隐藏在Prelude中的内容时。
下一步,decimal将返回一个完全独立的Integral a,所以不要把read放在它上面。实际上,您并不需要int函数。Haskell的类型检查器足够智能,可以将函数中的Integral a与Int统一起来,所以只需使用普通的老式decimal即可。
发布于 2013-06-15 07:41:38
您需要从Data.Attoparsec.Text导入takeWhile,否则编译器将使用Prelude中的。
import Data.Attoparsec.Text (takeWhile)
import Prelude hiding (takeWhile)decimal已返回Integral a;不需要read。
int :: Integral a => Parser a
int = decimalhttps://stackoverflow.com/questions/17118700
复制相似问题