So che èScala equivalente di do-la notazione di Haskell (ancora una volta)
do
x <- [1, 2, 3]
y <- [7, 8, 9]
let z = (x + y)
return z
può essere espressa in Scala come
for {
x <- List(1, 2, 3)
y <- List(7, 8, 9)
z = x + y
} yield z
Ma, soprattutto con monadi Haskell, Haskell ha spesso istruzioni all'interno del do
blocco che non corrisponde a <-
o =
. Ad esempio, ecco un codice di Pandoc che utilizza Parsec per analizzare qualcosa da una stringa.
-- | 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
Come si può vedere, si salva la posizione e l'ingresso, corre il parser sulla corda, e poi ripristina l'ingresso e la posizione prima di restituire il risultato.
Non riesco, per la vita di me, a capire come tradurre setInput str
, setInput oldInput
e setPosition oldPos
in Scala. Penso che avrebbe funzionato se ho appena messo le variabili senza senso in modo da poter utilizzare <-
, come
for {
oldPos <- getPosition
oldInput <- getInput
whyAmIHere <- setInput str
result <- parser
...
} yield result
ma non sono sicuro che sia il caso e, se è corretto, sono sicuro che ci deve essere un modo migliore per farlo.
Oh, e se puoi rispondere a questa domanda, puoi rispondere ancora una volta: per quanto tempo devo fissare Monads prima che non sentano la magia nera? :-)
Grazie! Todd
Se non si pianifica l'uso della variabile, è possibile sostituirlo con il carattere di sottolineatura: '_ <- setInput str' – incrop
Immagino che sia il modo più simile a Scala di farlo. – TOB
Non sono sicuro che sarebbe effettivamente possibile, ma questo potrebbe sembrare più naturale spostando queste affermazioni nel corpo del for, dove si può davvero andare a uno stile procedurale. – dividebyzero