I know that Haskell's
do
x <- [1, 2, 3]
y <- [7, 8, 9]
let z = (x + y)
return z
can be expressed in Scala as
for {
x <- List(1, 2, 3)
y <- List(7, 8, 9)
z = x + y
} yield z
But, especially with monads, Haskell often has statements inside the do
block that don't correspond to either <-
or =
. For example, here's some code from Pandoc that uses Parsec to parse something from a string.
-- | 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
As you can see, it saves the position and input, runs the parser on the string, and then restores the input and position before returning the result.
I can't for the life of me figure out how to translate setInput str
, setInput oldInput
, and setPosition oldPos
into Scala. I think it would work if I just put nonsense variables in so I could use <-
, like
for {
oldPos <- getPosition
oldInput <- getInput
whyAmIHere <- setInput str
result <- parser
...
} yield result
but I'm not sure that's the case and, if it is correct, I'm sure that there must be a better way to do this.
Oh, and if you can answer this question, can you answer one more: how long do I have to stare at Monads before they don't feel like black magic? :-)
Thanks! Todd