2012-05-04 6 views
17

私はHaskellのScalaの同等(再び)

do 
    x <- [1, 2, 3] 
    y <- [7, 8, 9] 
    let z = (x + y) 
    return z 

for { 
    x <- List(1, 2, 3) 
    y <- List(7, 8, 9) 
    z = x + y 
} yield z 

としてScalaで表される。しかし、特にモナドとすることができ、Haskellはしばしば内のステートメントを持っていることを知っていますdoブロックは<-または=に対応していません。たとえば、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 strsetInput oldInputsetPosition oldPosをScalaに翻訳する方法がわかりません。私はちょうど

for { 
    oldPos <- getPosition 
    oldInput <- getInput 
    whyAmIHere <- setInput str 
    result <- parser 
    ... 
} yield result 

のようなので、私は<-を使用することができでナンセンス変数を置けば、それは働くだろうと思いますが、私はそれはケースだか分からないと、それが正しければ、私がしなければならないことを確信していますこれを行うためのより良い方法です。

ああ、あなたはこの質問に答えることができます。あなたはもう1つ答えてもらえますか?黒い魔法のように感じる前に、モナドを何度見なければなりませんか? :-)

ありがとう! Todd

+7

変数の使用を計画していない場合は、その名前をアンダースコアで置き換えることができます: '_ < - setInput str' – incrop

+0

これはスカラーのような方法です。 – TOB

+0

確かに可能かもしれませんが、これらのステートメントをforの本体に移動すると、より自然なように見えるかもしれません。実際にプロシージャスタイルに進むことができます。 – dividebyzero

答えて

24

はい、その翻訳は有効です。

do { x <- m; n }は、m >>= \x -> nに相当し、do { m; n }は、m >> nと等価です。 m >> nm >>= \_ -> nと定義されているため(_は「この値を何かにバインドしない」という意味です)、それは確かに有効な変換です。 do { m; n }do { _ <- m; n }またはdo { unusedVariable <- m; n }と同じです。

doブロック内に変数バインディングのないステートメントは、通常、意味のある結果がないため、結果を無視します。たとえば、putStrLn "Hello, world!"の結果と関係がないので、その結果を変数にバインドしません。

(黒い魔法のモナドは、実際には複雑ではないということがありますが、より深い意味を見つけようとするのは、一般的にどのように動作するかを知る生産的な方法ではありません。特に一般的である計算を構成するためのインターフェイスだけです。私は、Haskellの抽象的なタイプメスをしっかりと把握するためにTypeclassopediaを読むことをお勧めします。しかし、多くを得るためには一般的なHaskellの紹介を読む必要があります)

+1

Scalaが '>>'に対して砂糖を提供しない理由は何ですか? –

+0

スカラはforの形でモナド理解を提供するので、私は思う。たぶん、計算の順序は維持されません。編集:それは維持されているように思わない。 –

+1

Monadの答えは本当に良いです。それは単なるプログラミングパターンです。非常に「黒い魔法」はありません。 –