Scala odpowiednik notacji Haskella (jeszcze raz)
Wiem, że to Haskell
do
x <- [1, 2, 3]
y <- [7, 8, 9]
let z = (x + y)
return z
można wyrazić w Scali jako
for {
x <- List(1, 2, 3)
y <- List(7, 8, 9)
z = x + y
} yield z
Ale, szczególnie w przypadku monad, Haskell często ma oświadczenia wewnątrzdo
blok, który nie odpowiada żadnemu<-
lub=
. Na przykład, oto kod z Pandoc, który używa Parsec do parsowania czegoś z ciągu znaków.
-- | 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
Jak widać, zapisuje pozycję i dane wejściowe, uruchamia analizator składni na łańcuchu, a następnie przywraca dane wejściowe i pozycję przed zwróceniem wyniku.
Nie mogę przez całe życie wymyślić, jak tłumaczyćsetInput str
, setInput oldInput
, isetPosition oldPos
do Scala. Myślę, że to zadziałałoby, gdybym po prostu włożył bzdurne zmienne, abym mógł użyć<-
, lubić
for {
oldPos <- getPosition
oldInput <- getInput
whyAmIHere <- setInput str
result <- parser
...
} yield result
ale nie jestem pewien, czy to przypadek, a jeśli jest poprawny, jestem pewien, że musi być lepszy sposób na to.
Aha, a jeśli potrafisz odpowiedzieć na to pytanie, czy możesz odpowiedzieć jeszcze raz: jak długo muszę wpatrywać się w Monady, zanim nie poczują się jak czarna magia? :-)
Dzięki! Todd