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
どちらにも対応しないステートメントを持っていることがよくあります。たとえば、Parsec を使用して文字列から何かを解析する Pandoc のコードを次に示します。<-
=
-- | 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
しかし、それが正しいかどうかはわかりません。もしそれが正しければ、これを行うためのより良い方法があるに違いないと確信しています。
ああ、この質問に答えられるなら、もう 1 つ答えてもらえますか: モナドがブラック マジックのように感じられなくなるまで、どれくらいモナドを見つめていなければなりませんか? :-)
ありがとう!トッド