我如何让Parsec叫我`read` :: Int? [英] How do I get Parsec to let me call `read` :: Int?

查看:85
本文介绍了我如何让Parsec叫我`read` :: Int?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下内容,可以进行类型检查:

I've got the following, which type-checks:

p_int = liftA read (many (char ' ') *> many1 digit <* many (char ' '))

现在,正如函数名称所暗示的那样,我希望它给我一个整数.但是,如果我这样做:

Now, as the function name implies, I want it to give me an Int. But if I do this:

p_int = liftA read (many (char ' ') *> many1 digit <* many (char ' ')) :: Int

我收到此类型错误:

Couldn't match expected type `Int' with actual type `f0 b0'
In the return type of a call of `liftA'
In the expression:
    liftA read (many (char ' ') *> many1 digit <* many (char ' ')) ::
      Int
In an equation for `p_int':
    p_int
      = liftA read (many (char ' ') *> many1 digit <* many (char ' ')) ::
          Int

是否有一种更简单,更简洁的方法来解析可能具有空格的整数?或解决此问题的方法?

Is there a simpler, cleaner way to parse integers that may have whitespace? Or a way to fix this?

最终,我希望它成为以下内容的一部分:

Ultimately, I want this to be part of the following:

betaLine = string "BETA " *> p_int <*> p_int  <*> p_int <*>
           p_int <*> p_parallel <*> p_exposure <* eol

这是用来解析看起来像这样的行:

which is to parse lines that look like this:

BETA  6 11 5 24 -1 oiiio

因此,我最终可以调用BetaPair构造函数,该构造函数将需要这些值(一些为Int,一些为其他类型,例如[Exposure]和Parallel)

So I can eventually call a BetaPair constructor which will need those values (some as Int, some as other types like [Exposure] and Parallel)

((如果您很好奇,这是一种文件格式的解析器,除其他外,它代表蛋白质中的氢键合的β链对.我无法控制该文件格式!)

(if you're curious, this is a parser for a file format that represents, among other things, hydrogen-bonded beta-strand pairs in proteins. I have no control over the file format!)

推荐答案

p_int是一个生成Int的解析器,因此类型将为Parser Int或类似¹.

p_int is a parser that produces an Int, so the type would be Parser Int or similar¹.

p_int = liftA read (many (char ' ') *> many1 digit <* many (char ' ')) :: Parser Int

或者,您可以键入read函数(read :: String -> Int)来告诉编译器表达式具有哪种类型.

Alternatively, you can type the read function, (read :: String -> Int) to tell the compiler which type the expression has.

p_int = liftA (read :: String -> Int) (many (char ' ') *> many1 digit <* many (char ' ')) :: Int

关于更清洁的方式,请考虑将many (char ' ')替换为spaces.

As for the cleaner ways, consider replacing many (char ' ') with spaces.

¹ParsecT x y z Int

这篇关于我如何让Parsec叫我`read` :: Int?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆