問題タブ [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 - モナドを使用したよりエレガントなコードのヒント?
私はついにモナドの使い方を理解しました(私がそれらを理解しているかどうかはわかりません...)が、私のコードは決して非常にエレガントではありません。Control.Monad
これらすべての機能が実際にどのように役立つかについての理解が不足しているためだと思います。したがって、状態モナドを使用して、特定のコードでこれに関するヒントを求めるのがよいと思いました。
このコードの目的は、さまざまな種類のランダムウォークを計算することです。これは、より複雑なものの前に私がやろうとしていることです。問題は、同時に2つのステートフル計算があり、それらを優雅に構成する方法を知りたいということです。
- 乱数発生器を更新する関数は、ある種のものです。
Seed -> (DeltaPosition, Seed)
- ランダムウォーカーの位置を更新する関数は、ある種のタイプです
DeltaPosition -> Position -> (Log, Position)
(Log
ランダムウォーカーの現在の位置を報告するための何らかの方法があります)。
私がやったことはこれです:
この2つのステートフル計算を構成する関数があります。
次に、それを状態を構成する関数に変換します。
そして、私は最も単純なものを持っています。たとえば、現在の位置に乱数を合計するだけのランダムウォーカーです。
そしてこれを繰り返し行う関数:
そして、これをロードしghci
て実行すると、次のようになります。
ランダムウォーカーが占める位置のリストである、私が欲しいものを手に入れます。しかし...これを行うにはもっとエレガントな方法があるに違いないと思います。2つの質問があります:
の巧妙な関数を使用して、これらの関数をより「モナディック」な方法で書き直すことはできます
Control.Monad
か?このような状態の組み合わせで使用できる一般的なパターンはありますか?これはモナド変換子などと関係がありますか?
list - Listパッケージのモナディックリストを使用するコードが非常に遅いのはなぜですか?
先週、ユーザーMasseは、Haskellのディレクトリにファイルを再帰的にリストすることについて質問しました。List
私が最初に考えたのは、パッケージのモナディックリストを使用して、印刷を開始する前にリスト全体をメモリに作成しないようにすることでした。私はこれを次のように実装しました:
これは、すぐに印刷を開始し、メモリをほとんど使用しないという点で美しく機能します。FilePath -> IO [FilePath]
残念ながら、同等のバージョンよりも数十倍遅くなります。
私は何が間違っているのですか?List
このようなおもちゃの例以外のパッケージを使用したことListT
がないので、どのようなパフォーマンスが期待できるかわかりませんが、40,000ファイルまでのディレクトリを処理するのに30秒(数分の1秒)もかかるようですスロー。
haskell - Haskell:リフトとリフトIO
どのような状況liftIO
で使用する必要がありますか? を使用している場合ErrorT String IO
、lift
関数は IO アクションを に持ち上げるために機能するErrorT
ため、liftIO
余分なようです。
haskell - エラー処理も行う状態モナドを書くにはどうすればよいですか?
エラー処理もサポートできる状態モナドを書く必要があります。エラーの原因についての詳細も提供できるため、この目的のために、Either モナドを使用することを考えていました。Maybe モナドを使用して状態モナドの定義を見つけましたが、Maybe の代わりに Each を使用するように変更することはできません。コードは次のとおりです。
haskell - StateTとStateモナドの組み合わせ
私が機能を持っているとしましょう
および関数:
f
で使用してg
、それらの間の状態を渡したいです。のライブラリ関数はあり
StateT (return . runState f)
ますか?または、一般的に、対応するモナドを持つモナド変換子が与えられた場合、そのためのライブラリ関数はありますか?
json - Text.JSON の Result 型の liftIO のインスタンスを作成する
Haskell の Text.JSON ライブラリは Result と呼ばれる抽象データ型を使用します。これは基本的には Maybe の形式ですが、Nothing の代わりに Error String があります。とにかく、JSON.readJSON の実装内で、liftIO を使用して、IO を返す関数呼び出しを Result に変換する必要があります。私はモナドトランスフォーマーに不慣れで、結果にliftIOを実装できないようです(ghciによると、無限型を構築しようとしています)。
何か案は?
どうもありがとう
編集
申し訳ありませんが、詳しく説明するのに時間がかかりました。皆さんの助けに感謝します。
したがって、return の前の最後の行では、getSiteTitle を使用して、その URL の Web サイトのタイトルを解析します。ただし、その関数は IO String の型を返し、コンパイラはそれを Result にしたいと言います。これは不可能ですか?
再度、感謝します!
EDIT2
データ型からタイトルを削除し、後で IO モナド内で取得することにしました。みんなの助けに感謝します!私は確かにこの問題から学びました。
haskell - モナド変換子コンテキストのモナド
モナドとモナド変換子をつかむのに苦労しています。次の不自然な例があります(コンパイルできません):
readEither の機能を readEitherT にコピーすると機能しますが、既存の readEither 関数の機能を活用できるのではないかとしつこく感じていますが、その方法がわかりません。readEitherT 関数で readEither を持ち上げようとすると、必要に応じて持ち上げられErrorT String IO
(Either String Int)
ます。しかし、どうにかして に到達する必要がありErrorT
String IO Int
ます。
これで間違った方向に進んでいる場合、IO(または他のモナド)を必要とし、モナドコンテキストから呼び出されるエラーを処理する正しい方法は何ですか(foo
例の関数を参照)
編集: どうやら、私がやろうとしていたことは明らかではありませんでした。たぶん、次の関数は、私が疑問に思っていたことと理由を説明しています
これは機能しますが、バインドのためにまだ醜いです。これは、大文字と小文字をチェックしていた以前のバージョンよりもはるかに明確です。これはこれを行うための推奨される方法ですか?
haskell - 関数をモナド変換子にラップすることは悪い習慣と見なされますか?
モナドを使いたいとしましょう。それから、リスト内でルックアップをしたいとしReaderT [(a,b)]
ます。Maybe
これを行う簡単で、あまり珍しくない方法は次のとおりです。
最初の可能性
ただし、これは、ReaderT トランスフォーマーがどのように機能するかについて、自明ではないことを主張しているように見えます。Control.Monad.Reader のソース コードを見ると、これが問題なく動作することが明らかです。しかし、これを裏付けるドキュメントを読んだことがありません。しかし、次のように find を書くこともできます:
第二の可能性
MaybeT
同様のアイデアは、 、StateT
、State
およびのラッピングにも適用されReader
ます。通常、私は最初の例のように書きますが、ほとんどの場合、2 番目の例のように書く方法は明らかであり、読みやすいとさえ言えます。だから私の質問は: 最初の例のようなコードは悪いと考えるべきですか?
monads - 新しいモナド変換子を作成するときに定型文を作成する理由
Real World Haskellの本のこのセクションhttp://book.realworldhaskell.org/read/monad-transformers.html#id659032MonadState
は、新しいモナド変換子を作成するときに、、MonadIO
などのインスタンスを手動で導出する必要があることを示唆しています。
しかし、私は以下を試し、それをコンパイルしました。なぜ図書館で行われないのですか?
私がMaybeT
モナド変換子を持っているとしましょう:
t
それがaMonadTrans
でありm
、であることがわかったらMonad
、なぜ他のすべてをこのように自動的に導出できないのでしょうか。
著者は、新しいものごとにこれを手動で行う必要があることを意味しますか、MonadTrans
それとも私は彼を間違えますか?
どうもありがとうございます :)
haskell - Haskellのベストプラクティス:Haskelineでの早期終了
私はHaskelineパッケージを使用していて、何かをする前にコマンドラインから3つの文字列を続けて取得したいと思っています。そして、私にとってはきちんとした解決策と思われるものを思いつきました。しかし、私はそれを行うためのより良い方法があるかもしれないと確信しています。Haskelineパッケージを使用しているときのベストプラクティスを探しています。次のサンプルコードのメリットを評価してください。
ご覧のとおり、早期終了のタスクを実行しますが、それでも少し厄介に見えます。notNothingとgetInputLineを次のような1行に変換しようと考えています。
それほど悪くはないと思います。それはかなり明確で簡潔だと思います(ただし、タイプチェックは行わないため、タイプチェックを行うバージョンを作成する必要があります)。
しかし、これは私が思いついた最高のものであり、私の質問は最終的に次のとおりです。このコードをよりきれいで読みやすくするためにどのように改善しますか?私も正しい方向に進んでいますか?
編集:あなたのガードが'a / = Nothing'以外のものである場合、私が今発見した素晴らしいヘルパー関数は次のとおりです。
それからあなたは書くことができるので(luquiが提案したように):
これはかなりクールです。しかし、Nothingとのみ一致している場合は、TomMDの答えの方が優れています。