首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Attoparsec编译错误

Attoparsec编译错误
EN

Stack Overflow用户
提问于 2013-06-15 07:29:47
回答 2查看 306关注 0票数 0

我正在试着学习如何使用attoparsec。我正在尝试解析以下格式的文本文件:

代码语言:javascript
复制
id int
call_uuid string 30

我的代码如下:

代码语言:javascript
复制
{-# 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)

代码语言:javascript
复制
$ 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;
           .... }

我不确定这是与我的安装中损坏的包有关,还是我对类型不了解。提前感谢!

EN

回答 2

Stack Overflow用户

发布于 2013-06-15 07:41:52

这里有2个错误,首先在前言中takeWhile被定义为(a -> Bool) -> [a] -> [a]。您可能需要来自Data.Auttoparsec.TexttakeWhile,但您必须首先导入该文件并隐藏前置版本。

代码语言:javascript
复制
import Prelude hiding (takeWhile)
import Data.Attoparsec.Text (takeWhile)

但如果这段代码变得更大,我建议

代码语言:javascript
复制
import qualified Data.AttoParsec.Text (takeWhile) as AP

然后只使用AP.takeWhile,因为它更具可读性,因为当您不必到处查看隐藏在Prelude中的内容时。

下一步,decimal将返回一个完全独立的Integral a,所以不要把read放在它上面。实际上,您并不需要int函数。Haskell的类型检查器足够智能,可以将函数中的Integral aInt统一起来,所以只需使用普通的老式decimal即可。

票数 4
EN

Stack Overflow用户

发布于 2013-06-15 07:41:38

您需要从Data.Attoparsec.Text导入takeWhile,否则编译器将使用Prelude中的。

代码语言:javascript
复制
import Data.Attoparsec.Text (takeWhile)
import Prelude hiding (takeWhile)

decimal已返回Integral a;不需要read

代码语言:javascript
复制
int :: Integral a => Parser a
int = decimal
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17118700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档