我正在处理 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/