Я знаю, что Haskell
do
x <- [1, 2, 3]
y <- [7, 8, 9]
let z = (x + y)
return z
может быть выражен в Scala как
for {
x <- List(1, 2, 3)
y <- List(7, 8, 9)
z = x + y
} yield z
Но, особенно с монадами, Haskell часто содержит операторы внутри блока do
, которые не соответствуют ни <-
или =
. Например, вот некоторый код от Pandoc, который использует Parsec для разбора чего-то из строки.
-- | Parse contents of 'str' using 'parser' and return result.
parseFromString :: GenParser tok st a -> [tok] -> GenParser tok st a
parseFromString parser str = do
oldPos <- getPosition
oldInput <- getInput
setInput str
result <- parser
setInput oldInput
setPosition oldPos
return result
Как видите, он сохраняет позицию и ввод, запускает синтаксический анализатор строки, а затем восстанавливает ввод и позицию перед возвратом результата.
Я не могу понять, как перевести setInput str
, setInput oldInput
и setPosition oldPos
на Scala. Я думаю, что это сработает, если я просто вставлю бессмысленные переменные, чтобы использовать <-
, например
for {
oldPos <- getPosition
oldInput <- getInput
whyAmIHere <- setInput str
result <- parser
...
} yield result
, но я не уверен, что это так, и, если это правильно, я уверен, что должен быть лучший способ сделать это.
О, и если вы можете ответить на этот вопрос, можете ли вы ответить еще на один :как долго я должен смотреть на монад, прежде чем они перестанут ощущаться как черная магия?:-)
Спасибо! Todd