haskell - Haskell 中的绑定(bind)与赋值

标签 haskell compiler-errors monads assignment-operator do-notation

我正在处理 Write Yourself a Scheme教程,一个代码块让我想知道绑定(bind)和赋值之间的区别:

 parseAtom = do first <- letter <|> symbol
            rest <- many (letter <|> digit <|> symbol)
            let atom = first:rest
            return $ case atom of 
                       "#t" -> Bool True
                       "#f" -> Bool False
                       _    -> Atom atom

为什么let atom =而不是atom <- ?因此,我尝试:

parseAtom = do first <- letter <|> symbol
           rest <- many (letter <|> digit <|> symbol)
           atom <- first : rest
           return $ case atom of
                "#t" -> Bool True
                "#f" -> Bool False
                _ -> Atom atom

我得到编译错误:

    Couldn't match expected type `[Char]'
       against inferred type `Text.Parsec.Prim.ParsecT
                                String () Data.Functor.Identity.Identity Char'
In a stmt of a 'do' expression: atom <- first : rest

我无法准确地理解这意味着什么,这可能是由于对 do 的不准确理解所致。或单子(monad)。 (我已阅读 Learn You a Haskell 以及其他各种 monad/do 教程,并且其他 SO 问题指出缩进经常会导致此处出现问题,但我认为我缩进正确)

最佳答案

您位于解析器 monad 内部,因此 <- 的右侧需要是一个解析器表达式。然而first : rest只是一个列表(具体来说是一个字符串),而不是一个解析器表达式。

什么v <- someParser所做的是将给定的解析器应用于输入,然后将匹配的文本存储在 v 中。字符串不是解析器,它不能应用于输入,并且 v 中不会存储任何匹配的文本。 。因此,您所能做的就是将字符串存储在 v 中。 ,您可以通过写 let v = someString 来完成.

关于haskell - Haskell 中的绑定(bind)与赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17011780/

相关文章:

class - 在 Haskell 中,你可以创建类的对象吗?

java - 在编译器上编译成功的过程在在线编译器上失败了,为什么?

c++ - 使用外部库编译

haskell - 请求澄清 McBride/Paterson Applicative 论文中的转置示例

c++ - 这是以前做过的吗? (用于链式操作的 Monad View 包装 C++ 集合/类型)

functional-programming - Monad 组合(续·状态)

haskell - 对 Maybe 值列表进行操作

haskell - Haskell 中的 "Strategy Pattern"

haskell - DuplicateRecordFields 和函数组合

java - gradle:跳过任务 ':compileJava',因为它没有源文件