1

私はHaskellの初心者です。リーダーの作成方法と共有変数のクエリ方法を学びました。Hugs98のReader.hsのソースコードを調べてみた

instance Monad (Reader r) where
return a = Reader $ \_ -> a

m >>= k  = Reader $ \r -> 
                  runReader (k (runReader m r)) r

ここで (return a) は、値を取り、a を返す関数をラップする Reader を作成することがわかります。

m >>= k は私が理解できないものです。まず、それはどのように適用できますか?バインドされた2つのリーダーの例が役立つでしょうか?

第二に、実装は私にとっていくらかあいまいです。 k を (runReader mr) の結果に適用するポイントがわかりません。

ありがとう

4

5 に答える 5

3

リーダーは次のように定義されます。

newtype Reader r a = Reader { runReader :: r -> a }

したがって、実際には、r -> a追加のカプセル化を備えた型の関数にすぎません。Reader は実際にはモナド内のすべてのアクションに追加の入力を提供するだけなので、これは理にかなっています。

カプセル化を取り除き、関数のみを使用するr -> aと、モナド関数の型は次のようになります。

return :: a -> (r -> a) -- or: a -> r -> a
(>>=) :: (r -> a) -> (a -> (r -> b)) -> (r -> b) -- or: (r -> a) -> (a -> r -> b) -> r -> b

これを見ると、私たちに何が求められているかが簡単にわかります。型a -> (r -> a)を見て、これが と同等でa -> r -> aあることを確認すると、この関数を 2 つの方法で見ることができることがわかります。1 つは、 の引数を取り、a型の関数を返すことです。もう 1 つは、 と を取り、を返す関数r -> aとして見ることです。次のいずれかのビューを使用して return を実装できます。ara

return a = \r -> a -- or: return a r = a

バインドはよりトリッキーですが、同じロジックが適用されます。私が与えた最初の型シグネチャでは、型の 3 番目rの型も実際に入力であることはすぐにはわかりませんが、2 番目の型シグネチャはこれを非常に簡単に理解できるようにします。それでは、2 番目の型シグネチャの実装から始めましょう。

(>>=) rToA aAndRToB r = ...

したがって、 type の値、 typerの関数、r -> aおよび type の関数があり、そこa -> r -> bから type の値を作成することが目標ですb。唯一bの入力はa -> r -> b関数内にあるため、それを使用する必要がありますが、aフィードする がないため、取得する必要があります。r -> aがあれば、関数はそれを提供できますr。がありrます。これは 3 番目の入力です。したがって、次の値が得られるまで関数を単純に適用できますb

(>>=) rToA aAndRToB r = b where
  a = rToA r
  b = aAndRToB a r

ここで、r-value をすべてのアクション ( Reader モナドのゴール) に提供すると同時に、a-value をあるアクションから次のアクション( のゴール) に連鎖させていることがわかります(>>=)。次のように、最初の型シグネチャを模倣する方法でこれを記述することもできます。

(>>=) rToA aToRToB = \r -> (aToRToB (rToA r)) r

変数の名前を変更すると、Reader のバインドの定義と非常によく似ていますが、 and は使用ReaderしませんrunReader

m >>= k = /r -> k (m r) r
于 2013-08-28T08:27:24.073 に答える
1

では、 を見てみましょうm >>= k。ここmにリーダーがあり、リーダーを生成するk関数です。それで、これは何をしますか?

runReader m r

OK、これは読み取る入力として実行mされています。r

k (runReader m r)

これは実行からの出力を受け取り、mそれを に渡しkます。これにより、別のリーダーがk返されます。

runReader (k (runReader m r)) r

これは、によって返されたリーダーを受け取り、kそれを実行します (読み取り用の同じ入力rを使用)。

あなたはそれに従いますか?

于 2013-08-28T07:56:14.043 に答える
0

Readerの特定の型スキームを導き出し、>>=それを少し単純化しましょう。

-- General monad
(>>=) :: m a -> (a -> m b) -> m b

-- Reader monad
(>>=) :: Reader r a -> (a -> Reader r b) -> Reader r b

-- Let me put it in a (syntactically incorrect, but) more illustrative form
(>>=) :: (Reader r -> a) -> (a -> (Reader r -> b)) -> (Reader r -> b)

-- A reader is a function of type (r -> a), packed into a Reader context.
-- If we want to access the wrapped function, we can easily do it with runReader.

-- With this in mind, let's see how it would be without the extra context.
(>>=) :: (r -> a) -> (a -> (r -> b)) -> (r -> b)


(モナド値) と(関数) の>>=2 つのパラメーターを取り、 (別のモナド値)を返す関数 と考えることができます。 この単純化された型構造の実装を書きましょう。mfresult

-- Takes m and f, returns result
m >>= f = result

-- The types
m      :: r -> a
f      :: a -> (r -> b)
result :: r -> b

-- Implementation
m >>= f = \x -> (f (m x)) x

-- A quick How-We-Got-Here
mResult = m x  -- :: a
fResult = f mResult  -- :: r -> b
result  = \x -> fResult x
        = \x -> (f mResult) x
        = \x -> (f (m x)) x


ゲームに戻る時が来Readerました。フォームf >>= m = resultはそのままですが、型が少し変更され、実装も少し変更されます。

-- The types
m      :: Reader (r -> a)
f      :: a -> Reader (r -> b)
result :: Reader (r -> b)

-- Functions we easily used before, are now in a "Reader".
-- But we can easily unwrap and access them with "runReader".

-- Now "result" is not just a function, but one in a "Reader".
-- But we can easily wrap it with "Reader".

-- Apply these tools on our How-We-Got-Here analogy from before.
mResult = (runReader m) x  -- :: a
fResult = f mResult  -- :: Reader (r -> b)
result  = Reader $ \x -> (runReader fResult) x
        = Reader $ \x -> (runReader (f mResult)) x
        = Reader $ \x -> (runReader (f ((runReader m) x))) x


いよいよ実際の実装です。

m >>= f = Reader $ \x -> (runReader (f ((runReader m) x))) x

-- Remove the unnecessary parens
m >>= f = Reader $ \x -> runReader (f (runReader m x)) x

-- Different letters
m >>= k = Reader $ \r -> runReader (k (runReader m r)) r
于 2014-08-05T11:35:22.820 に答える