2

次のコードを理解するのが少し難しいです (IO の上に重ねられた ErrorT モナドで実行されます):

closePort [Port port] = liftIO $ hClose port >> (return $ Bool True)

>>よりも優先度が高い$。それで、Bool True最初に IO にラップされてから持ち上げられますか、liftIOそれともhClose最初に持ち上げられますか? つまり、IO モナドまたは ErrorT モナドで実行されますか>>?return

4

5 に答える 5

14

この場合、優先順位を気にする必要はありません。

liftIO (hClose port >> return (Bool True))

liftIO (hClose port) >> return (Bool True)

モナド変換子の法則により、同等でなければなりません。

  1. リフティングreturnは何もしません。

    lift . return = return
    
  2. 2 つのアクションのシーケンスを持ち上げることは、それらを別々に持ち上げることと同じです。

    lift (m >>= f) = lift m >>= (lift . f)
    

liftIOまた、これらの法律に従う必要があるため、

liftIO (hClose port >> return (Bool True))
= -- definition of >>
liftIO (hClose port >>= \_ -> return (Bool True))
= -- second monad transformer law
liftIO (hClose port) >>= \_ -> liftIO (return (Bool True))
= -- first monad transformer law
liftIO (hClose port) >>= \_ -> return (Bool True)
= -- definition of >>
liftIO (hClose port) >> return (Bool True)
于 2012-03-27T12:04:06.727 に答える
7

指定されたコードは次と同等です

closePort [Port port] = liftIO ( hClose port >> (return ( Bool True) ) )

したがって、全体(hClose port) >> (return (Bool True))が への引数liftIOです。したがって、(>>)returnは のものでありIO、全体のIO計算は で持ち上げられliftIOます。

于 2012-03-27T11:35:53.627 に答える
1

Bool(ここでは、定義した型のデータ コンストラクターを想定しています。)

liftIO $ hClose port >> (return $ Bool True)

と同じです

liftIO (hClose port >> (return (Bool True)))

したがって、return>>は両方ともIOバージョンであり、 の結果は>>外側のモナドに持ち上げられます。

于 2012-03-27T11:36:44.283 に答える
1

優先順位の高い演算子は、優先順位の低い演算子よりも強くバインドされます。

複数の演算子が式に含まれている場合の順序を理解するには、最も優先順位の高い演算子から始めて、両側の式を括弧で囲み、演算子の優先順位までこれを続けます。同じレベルの演算子については、定義された結合性に基づいて順序を決定します。グループ化があいまいであるため、同じ優先度レベルで異なる連想動作の演算子を混在させることは違法です。この手順は、おそらく数値演算子での作業に慣れているでしょう。

2 + 3 * 5 - 1 + 2
-- * is infixl 7
2 + (3 * 5) - 1 + 2
-- + and - are infixl 6, so apply parens starting at the left
(2 + (3 * 5)  - 1) + 2

((2 + (3 * 5)) - 1) + 2

>>は よりも優先順位が高いため$、 に同じ処理を適用します。

liftIO $ hClose port >> (return $ Bool True)

あなたにあげる

liftIO $ (hClose port >> (return $ Bool True))

したがって、最初にhCloseandreturn $ Bool Trueが type の式に結合されIO (Bool')、それが で持ち上げられliftIOます。(Bool'型が何であれどこにありますかBool True)。

Haskell Reportでは、構文、特に第 2 章、第 3 章、および第 9 章を徹底的に扱います。

于 2012-03-27T20:38:03.300 に答える
-2

次の実装を確認することをお勧めします$

($) :: (a -> b) -> a -> b
f $ x = f x

これは、xによって必要に応じて が評価されることを意味しfます。それまでは、私たちはそれを持っています

f $ expression for x = f (expression for x)

あなたの場合、私たちはそれを持っています

x = hClose port >> (return ( Bool True) )
f = liftIO

つまり、

f $ expression for x = f (expression for x)
                     = liftIO (expression for x)
                     = liftIO (hClose port >> (return ( Bool True) ))

それが明確になることを願っています。

于 2012-03-27T11:46:10.810 に答える