2017-08-15 16 views
6

Reader monadReaderTモナドトランスのthe documentationを見ています。* ReaderT Monad Transformerの*の目的は何ですか?

関連の定義は以下のとおりです。

newtype ReaderT k r m a :: forall k. * -> (k -> *) -> k -> * 
type Reader r = ReaderT * r Identity 

私は*の定義に何をしているか理解していません。特に私は、IOを基本モナドとし、r値のクラス制約としてReaderTから新しいモナドを導出しようとしています。

ReaderT(k)の4番目の入力があり、その位置に*を付けるとReaderがその値で何をしているのかわかりません。

+6

注意'ReaderT'のソースコードは' newtypeReadT rma = ReaderT {runReaderT :: r - > ma} 'です。 'k'は、' ReaderT'の多種多様性を強調するために、Haddockの文書でのみ生成されます( '-XPolyKinds'は定義されているモジュールで有効になっています)。 – Alec

+2

"基本モナドとしてIOを持ち、r値のクラス制約を持つReaderTから新しいモナドを導き出そうとしています" - これは解決するよりも多くの問題を引き起こす可能性があります( 'r' 'Reader'から' IO'にインスタンス化された 'ReaderT'からの新しい型の導出ではありません)なぜこれを行うのが' ReaderT'のポリキンド定義によって妨げられるのか分かりません。 @Alecのように、 'k'パラメータはhaddockのアーチファクトです - 実際は完全に暗黙的です。あなたは' ReaderT ::(* - > *) - > * - > * 'のふりをすることができます確かにそのタイプがあります)。 – user2407038

+0

@ user2407038とnicolasどちらも正しいです。制約は属しており、モナド定義ではなくインスタンス宣言に配置されます。 –

答えて

5

*は値を持つタイプの一種である:それはIntList Intなどのようなものを表します。..

forall kは必ずしもそういうのではないkを意味します。宣言したり操作したりすることはできますが、実行時の値と必ずしも関連付ける必要はありません。その1つの例は、追加の情報を持つ他のタイプを「装飾」したい場合です:刺繍タイプには、それに付加された値の種類はありません。それは「純粋な」情報です。値)

単にここ

より、あなたはReaderにそれがすべて*に特化した取得し、mIdentityモナドに特化されていることがわかります。それがあなたのIOモナドが欲しい場所です。

制約は、型自体で指定しないことをお勧めします。 typeclassに添付された特定のメソッドを使用する使用時には、その場で追加されます。実際、メソッドを使用しない記述の理由は、呼び出し元に要求することによって負担を負わなければなりません。

(あなたは、Dictのように、他のインスタンスを推測するためにあなたがGADTとランタイム値として型クラスの証人をキャプチャするための非常に良い理由があるが、それはあなたがやりたいことはおそらくない場合を除き)

+0

あなたが正しいと思う。制約は属しており、モナド定義ではなくインスタンス宣言に配置されます。 –

関連する問題