問題タブ [monad-transformers]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
haskell - 厄介なモナド変換スタック
Google Code Jam の問題解決 ( 2009.1AA: "マルチベースの幸福" ) 厄介な (コード単位の) 解決策を思いついたので、それをどのように改善できるか興味があります。
簡単に言えば、問題の説明は次のとおりです。指定されたリストのすべての基数について、数字の二乗和を繰り返し計算すると 1 に達する、1 より大きい最小の数を見つけます。
elem
または擬似Haskellでの説明(無限リストに対して常に機能する場合に解決するコード):
そして私の厄介な解決策:
- ぎこちないというのは、この種のコードがあることを意味します。
happy <- lift . lift . lift $ isHappy Set.empty base cur
- isHappy 関数の結果をメモします。メモ化された結果マップに State モナドを使用する。
- 最初の解決策を見つけようとして、 (上記の疑似 Haskell のように)
head
and を使用しませんでした。これは、計算が純粋ではない (状態が変化する) ためです。filter
そのため、StateT をカウンターと共に使用して反復し、条件が満たされたときに計算を終了するために MaybeT を使用しました。 - すでに a の中にあり
MaybeT (StateT a (State b))
、条件が 1 つのベースに当てはまらない場合、他のベースをチェックする必要はないのでMaybeT
、スタックに別のベースがあります。
コード:
Haskell を使用している他の参加者は、より優れた解決策を持っていましたが、問題の解決方法が異なりました。私の質問は、私のコードに対する小さな反復的な改善についてです。
haskell - Haskellモナド変換子のスタックと型の署名
モナド変換子のスタックを作成しようとしていますが、関数の正しい型シグネチャを取得できません。(私はまだHaskellにかなり慣れていません)
スタックには、追跡する必要のある複数の状態(2つは倍増する可能性がありますが、すぐにわかります)とロギング用のWriterTがあるため、複数のStateTトランスフォーマーが組み合わされています。
これが私がこれまでに持っているものです:
状態や機能をpopLine
いじって状態に影響を与えてほしい。に渡される計算です。[Line]
xLineNum
Int
evalr
runPass1
コードをロードするたびに、一般的に次のようなエラーが発生します。
どの署名も正しくないようですが、popLineは最初の関数であるため、すぐにエラーが発生するのはpopLineだけです。
私はそれが型署名に示唆するものを追加しようとします(例えば:popLine :: (MonadState [Line] m) => ...
しかしそれからそれは次のようにエラーになります:
型変数ではないことをしようとすると、常にこのメッセージが表示されるようです。(MonadState s m)
他の何かでOKとエラーが好きなようですが、[a]
代わりにs
それを試してみると、上記のようなエラーが発生します。(最初は[Line]とIntが単一の状態でタプリングされていましたが、このエラーが発生していたので、別々の状態にしようと思いました)。
GHC 6.10.4、Kubuntu
だから、誰かが私に何が起こっているのかを教えて説明を与える/正しい型の署名を見せてくれるか、または誰かがこのようなものに関する良いリファレンスを知っていますか(これまでに役立ったのは「モナド変換子のステップバイステップ」だけでした) 、しかしそれはただ1つのaux状態関数と1つのStateTを使用しますか?
よろしくお願いします。
編集
これは、JFTとEdwardの提案を組み込んだコンパイルコードです。
私は結合incLineNum
し、ライターモナド部分を機能popLine
さnextLine
せる必要がありますが、ここからどこに行くべきかはわかっていると思います。みんなありがとう。
haskell - モナド変換器と複数のモナドのスタッキング
私は署名付きの関数とf
署名付きの関数を持っていますf :: [a] -> StateT Int Reader b [c]
f'
f' :: a -> StateT Int Reader b [c]
f の計算 (非常に単純化されています) は次のようになります。
[c]
そしての代わりに…の部分のx
++
部分[c]
をy
モナドのものを巻きつけて返したいと思います。
手動でアンラップせずにそれを達成し、手動で結果を再度まとめる可能性はありx
ますy
か? 単純なコードを取得するには、モナド スタックの一番下に List モナドが必要ですか? Reader モナドは明らかに MonadPlus クラスのインスタンスではありません。
haskell - ParsecでのMonadErrorの使用
MonadErrorをParsecと一緒に使用しようとしています。私は次のコードスニペットを思いついた:
ただし、 catchErrorret
はLeft "SomeError"
効果がないようです。ここでMonadErrorを使用する正しい方法は何ですか?
たとえば、次の場合のように、Parsec自体のエラー処理よりもMonadErrorを使用したいと思います。
ここでparser1が失敗した場合、parser2は続行されますが、解析を完全に中止する例外があります。
haskell - カスタム モナド トランスフォーマーを作成するために (>>=) 関数を実装しようとしたときのタイプ エラー
将来のプロジェクトのためにモナド変換子を作成しようとしていますが、残念ながら、モナド型クラスの (>>=) 関数の実装が機能しません。
まず、基礎となるモナドの実装は次のとおりです。
ここで、Monad 型クラスの実装は GHC によって ( GeneralizedNewtypeDeriving
language プラグマを使用して) 自動的に行われます。モナド変換子は次のように定義されます。
問題は、Monad typeclasse の (>>=) 関数をインスタンス化する方法に起因します。
私の見方では、最初は基礎となるモナド>>=
で実行されます。m
したがって、runRuntimeT x >>=
タイプの値を返しますRuntime a
(そうですか?)。次に、次のコードid >>=
は type の値を返す必要がありますa
。この値は、 type の関数 f に渡されf :: (Monad m) => a -> RuntimeT m b
ます。
ここで型の問題が発生します。f
関数の型が (>>=) 関数で必要な型と一致しません。これを首尾一貫させることができますか?これが機能しない理由はわかりますが、機能的なものに変えることはできません。
編集:エラーメッセージ:
助けてくれてありがとう、
チャーリー P.
typeclass - Maybe-Transformer MaybeTをMonadWriterのインスタンスにするにはどうすればよいですか?
Real World Haskell、Chapter Monad Transformersの例に基づいて、MaybeT-TransformerMonadを構築しようとしています。
これは正常に機能しますが、MaybeTをMonadWriterのインスタンスにします。
テルは大丈夫ですが、リッスン機能を正しく取得できません。コンストラクター折り紙の1日半後に私が思いつくことができる最高のものはあなたが上で見るものです:アンラップは(多分a、w)のタプルであるはずであり、多分タイプでラップしたいです全部を空のMonadWriterに入れます。
しかし、コンパイラは次のように文句を言います。
私は何が欠けていますか?
design-patterns - 野生のモナドトランスフォーマーに遭遇した人はいますか?
私のビジネス分野 (金融機関のバック オフィス IT) では、ソフトウェア コンポーネントがグローバルな構成を保持し、その進行状況をログに記録し、ある種のエラー処理や計算の短絡を行うことは非常に一般的です。 Haskell の Reader、Writer、Maybe モナドなどでうまくモデル化でき、モナド変換子と一緒に構成できます。
しかし、いくつかの欠点があるようです: モナド変換子の背後にある概念は非常にトリッキーで理解しにくく、モナド変換子は非常に複雑な型シグネチャにつながり、パフォーマンスにいくらかのペナルティを課します。
だから私は疑問に思っています:上記の一般的なタスクを扱うとき、モナド変換子はベストプラクティスですか?
haskell - mtl、トランスフォーマー、monads-fd、monadLib、および選択のパラドックス
Hackage には、モナド変換子用のパッケージがいくつかあります。
- mtl : モナド変換ライブラリ
- トランスフォーマー: 具体的なファンクターとモナドのトランスフォーマー
- monads-fd : 機能依存関係を使用するモナドクラス
- monads-tf : 型ファミリーを使用したモナドクラス
- monadLib : モナド変換子のコレクション。
- mtl-tf : 型ファミリーを使用したモナド変換ライブラリ。
- mmtl : Modular Monad Transformer ライブラリ
- mtlx : 型インデックスを持つ Monad 変換ライブラリで、「無料」のコピーを提供します。
- compose-trans : 構成可能なモナド変換子
(そして多分私はいくつかを逃した)
どちらを使用しましょうか。
mtl は Haskell Platform のものですが、reddit ではクールではないという声をよく耳にします。
しかし、とにかく選択の何が悪いのか、それは良いことだけではありませんか?
たとえば、 data-accessor の作成者が、一般的な選択肢だけに対応するために、これらすべてを作成する必要があることを見てきました。
- data-accessor-monadLib ライブラリ: monadLib のモナドのアクセサ関数
- data-accessor-monads-fd ライブラリ: Accessor を使用して monads-fd State モナド クラスの状態にアクセスします
- data-accessor-monads-tf ライブラリ: Accessor を使用して monads-tf State モナド型ファミリの状態にアクセスします
- data-accessor-mtl ライブラリ: Accessor を使用して mtl State モナド クラスの状態にアクセスします
- data-accessor-transformers ライブラリ: Accessor を使用して変換器の状態にアクセスする State モナド
これが続けば、たとえばいくつかの競合する Arrow パッケージが進化すると、次のようなものが表示されるのではないかと想像します。
そして、spoonklink が fork されると、Hackage がディスク容量を使い果たしてしまうのではないかと心配しています。:)
質問:
- モナド変換パッケージがこれほど多いのはなぜですか?
- mtl がクールでないのはなぜですか?
- 主な違いは何ですか?
- これらの一見競合するパッケージのほとんどは、Andy Gill によって作成され、Ross Paterson によって保守されています。これは、これらのパッケージが競合するのではなく、何らかの形で連携するということですか? Andy と Ross は、独自のパッケージのいずれかを時代遅れと見なしていますか?
- あなたと私はどちらを使うべきですか?
haskell - モナド変換子での型同義語の使用
モナド変換子の型コンストラクターの引数として型同義語を使用することは可能ですか?特に、適用されたモナド変換子に単項型の同義語がある場合、それを別のモナド変換子の基になるモナドの型として使用できますか?
私が見たところ、型の同義語はファーストクラスの型コンストラクターとして受け入れられていません。以下の例とエラーメッセージを参照してください。
A
の定義で型の同義語を拡張しないようにする方法はありB a
ますか?
haskell - モナドを使用したよりエレガントなコードのヒント?
私はついにモナドの使い方を理解しました(私がそれらを理解しているかどうかはわかりません...)が、私のコードは決して非常にエレガントではありません。Control.Monad
これらすべての機能が実際にどのように役立つかについての理解が不足しているためだと思います。したがって、状態モナドを使用して、特定のコードでこれに関するヒントを求めるのがよいと思いました。
このコードの目的は、さまざまな種類のランダムウォークを計算することです。これは、より複雑なものの前に私がやろうとしていることです。問題は、同時に2つのステートフル計算があり、それらを優雅に構成する方法を知りたいということです。
- 乱数発生器を更新する関数は、ある種のものです。
Seed -> (DeltaPosition, Seed)
- ランダムウォーカーの位置を更新する関数は、ある種のタイプです
DeltaPosition -> Position -> (Log, Position)
(Log
ランダムウォーカーの現在の位置を報告するための何らかの方法があります)。
私がやったことはこれです:
この2つのステートフル計算を構成する関数があります。
次に、それを状態を構成する関数に変換します。
そして、私は最も単純なものを持っています。たとえば、現在の位置に乱数を合計するだけのランダムウォーカーです。
そしてこれを繰り返し行う関数:
そして、これをロードしghci
て実行すると、次のようになります。
ランダムウォーカーが占める位置のリストである、私が欲しいものを手に入れます。しかし...これを行うにはもっとエレガントな方法があるに違いないと思います。2つの質問があります:
の巧妙な関数を使用して、これらの関数をより「モナディック」な方法で書き直すことはできます
Control.Monad
か?このような状態の組み合わせで使用できる一般的なパターンはありますか?これはモナド変換子などと関係がありますか?