我正在经历Write Yourself a Scheme in Haskell .这是一个很棒的教程,但我遇到了 parsing exercises 之一:
parseNumber :: Parser LispVal
parseNumber = liftM (Number . read) $ many1 digit
使用以下方法重写 parseNumber:
我对 do-notation 没有任何问题:
parseNumber :: Parser LispVal
parseNumber = do x <- many1 digit
let y = read x
return $ Number y
对于#2,我尝试了很多变体,例如:
parseNumber :: Parser LispVal
parseNumber = (many1 digit) >>= (liftM (Number . read))
但我一直遇到类型错误。我有两个问题。
我觉得我缺少关于类型的基本概念?
最佳答案
您正在尝试从 do-notation 到 bind notation 的非平凡转换,我建议以“平凡”的方式进行,然后使其无积分。
记起:
x <- m === m >>=\x ->
让 x = e === 让 x = e 在
然后你有:
parseNumber = many1 digit >>=\x ->
让 y = 读入 x
返回(数字 y)
(我删除了 $
以避免出现优先级问题。)
然后我们可以将其转换为:
parseNumber = many1 digit >>=\x -> return (Number (read x))
= many1 digit >>= return .数字 。读
现在,如果你想使用 liftM
,您需要停止使用绑定(bind),因为提升的函数需要一个单子(monad)值作为其参数。
parseNumber = liftM (Number . read) (many1 digit)
关于haskell - 一元类型混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5320528/