【问题标题】:Parse error in a `do` block on input `<-`在输入`<-`的`do`块中解析错误
【发布时间】:2015-10-04 12:18:21
【问题描述】:

在我的教科书中,有一个例子说明如何使用解析器从字符串中取出第一个和第三个字符。我试着把它写下来,就像它在书中的样子。

type Parser a = String -> [(a,String)]

item = \inp -> case inp of
    []-> []
    (x:xs) -> [(x,xs)]

p = do 
    x <- item
    item 
    y <- item
    return (x,y)

但是我得到了消息:

dataTest.hs:47:11:
parse error on input ‘<-’
Perhaps this statement should be within a 'do' block?

由于我无法弄清楚出了什么问题,我写下了这个代码的不那么抽象的版本:

q = item >>= \x1 -> 
    item >>= \x2 ->
    item >>= \x3 -> 
    return (x1, x3)

但是如下图:

*Main> q "abc"
([('a',"bc")],[('a',"bc")],[('a',"bc")])

我得到了错误的输出。

所以我有两个问题:

  1. p 应该怎么写?
  2. 我应该怎么写q?

【问题讨论】:

  • 我有一种预感,item 的定义是错误的(它不应该只是一个函数,这使得它在解析器中是完全错误的 monad),并且如果它编译像这样,那么Parser的定义也是错误的(也许是用type定义的?你不能为type定义的东西定义自己的monad。)
  • 我将发布我是如何编写解析器的。
  • 对,这就是我的想法。对于具有该类型定义的解析器,您将无法使 do 表示法正常工作。
  • 在那种情况下,我的书有错误的定义。你能发布真正的定义吗?
  • @mcNogard 问题出在实例上。让它成为一个 Monad。

标签: haskell monads parse-error


【解决方案1】:

这只是一个格式化的东西。开始换行:

p = do
    x <- item
    item
    y <- item
    return (x,y)

至于q,记住do {x &lt;- item; f x}等价于item &gt;&gt;= \x -&gt; f x,第二个是多余的,所以:

q = do
    x1 <- item 
    item
    x3 <- item
    return (x1, x3)

...相当于p

【讨论】:

  • p 现在正在编译,但它仍然给我错误的结果。 p "abcd" 给出结果 ([('a',"bcd")],[('a',"bcd")],[('a',"bcd")])。我想得到结果[('a', 'c'), "d"],这就是我书中的结果。
  • @mcNogard 你可能不小心写了内联item。即,它应该只是do {x &lt;- item; y &lt;- item; return (x,y)} 或只是应用风格的(,) &lt;$&gt; item &lt;*&gt; item。这可能就是你要找的。但这是另一个问题。
  • 啊,但是等等:你正在使用函数 monad,而不是 Parser monad!您需要将 Parser 定义为另一种类型并创建一个 monad 实例。当然,如果你没有使用正确的 monad,它是行不通的!
猜你喜欢
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 2014-02-07
  • 2013-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多