2011-07-06 5 views
2

簡単な質問を形成Haskellの単項は

do let x = e1 
    e2 

および

do x <- e1 
    e2 

は両方ともe1を評価し、それをe2にバインドし、e2を評価します。

はい?

答えて

4

のはMaybeモナドに簡単な例をやってみましょう:

foo = do 
     let x = Just 1 
     return x 

の両方を脱糖
bar = do 
     x <- Just 1 
     return x 

、我々は、参考のため

foo = let x = Just 1 in return x -- do notation desugaring 
    = return (Just 1)    -- let 
    = Just (Just 1)     -- definition of return for the Maybe monad 

bar = let ok x = return x in Just 1 >>= ok -- do notation desugaring 
    = let ok x = return x in ok 1 -- definition of >>= for the Maybe monad 
    = return 1      -- definiton of ok 
    = Just 1      -- definition of return for the Maybe monad 

を取得し、私はtranslation from section 3.14 of the Haskell 2010 Reportを使用しています。

0

番号x <- e1は、e1 >>= \x ->の不完全な式に変換されます。 letの表現はちょうど普通のletです。または、let(>>=)が同じものかどうか尋ねていますか?彼らは非常にそうではありません:(>>=)は、モナドに包まれたものを関数に公開します。モナドに包まれたものを生成する必要があります。つまり、x <- e1の場合、e1のタイプはaの場合はIO aである必要がありますが、let x = e1の場合はe1のタイプはちょうどaです。いずれの場合もxのタイプはaとなります。

+0

'do'-expressionの' let'は普通の 'let'式だけではありません。これは 'let'ステートメントです(Haskell 2010レポート、セクション3.14)。 'let'文は' let'式にはなりませんが、それ自体は 'let'式ではありません。同様に 'e1 >> = \ x - >'は無意味です。レポートの翻訳ルールを見るだけの方がよいでしょう。 – Lambdageek

1

e1がタイプMonad m => m aの計算であると仮定すると、let x = e1x <- e1は多少異なることを意味します。

let -versionでは、do式内でxを使用すると、タイプMonad m => m aの値が扱われます。

do形式内でxを使用すると、aの値が扱われます(do-notationは暗黙的にモナド上のマッピングを処理するため)。例えば

e :: IO Int 
f :: Int -> Int 

-- the following will result in a type error, since f operates on `Int`, not `IO Int`: 
g = do let x = e 
     return $ f x 

-- the following will work: 
g' = do x <- e 
     return $ f x 
+0

ありがとうございます。モナドは私に量子力学を思い出させる - 「あなたがそれらを理解していると思うなら、あなたはしない」! :-) – guthrie

+0

私の例では; e :: Int、 "let"はうまくいくでしょうし、矢印ではありません - はい? – guthrie

+0

@Guthrieああ、 'e :: Int'なら' let'を使う必要があります。 –

3

いいえ、彼らは同じではありません。例えば、

do let x = getLine 
    print x 

let x = getLine in print x 

に変換xタイプIO Stringを有することになるように、これは、タイプ・エラーです。その結果ではなく、計算自体を印刷するように求めています。


do x <- getLine 
    print x 

ここ

getLine >>= \x -> print x 

xに変換計算の結果として結合し、そのタイプはStringあるので、このタイプチェックされています。それはいつものように<-結果、計算のに名前を結合させ、モナド結合を実行するために使用されている間


do -notation、letだけで、名前に値をバインドします。

+0

ありがとう、非常に明確な - 別のものへのバインディング。 – guthrie