問題タブ [st-monad]
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 - Haskell-デュアルパーソナリティIO/STモナド?
現在、評価にSTモナドを使用しているコードがいくつかあります。runST
メソッドが純粋な結果を生成し、そのような結果を安全に呼び出すことができることを示しているため、IOをどこにでも配置しないのが好きです(に対してunsafePerformIO
)。ただし、一部のコードが長くなっているため、デバッグ用のprintステートメントをに入れたいと思います。
STまたはIO(タイプまたは「isDebug」フラグに応じて)のデュアルパーソナリティモナド[またはタイプクラスの機械]を提供するクラスはありますか?SPJが彼の「FunwithTypeFunctions」の論文で「Mutation」クラスを紹介したことを思い出します。このクラスでは、結合型を使用してIOをIORefに、STをSTRefに関連付けました。そのようなものはどこかにパッケージとして存在しますか?
編集/解決策
どうもありがとうございました[n回目]、CA McCann!pdebug
そのソリューションを使用して、関数をサポートするモナド用の追加のクラスを導入することができました。ST
モナドはこれらの呼び出しを無視しますが、実行IO
しputStrLn
ます。
これはghciに非常に幸運な結果をもたらします。式はデフォルトでIOタイプであると想定されているため、「test 3」のようなものを実行すると、IOモナドが実行されるため、簡単にデバッグして、実際に実行するときに「testR」のようなもので呼び出すことができます。それ。
haskell - MonadPlus (ST a) インスタンスが必要
Typed Logical Variables in Haskellという論文を読んでいますが、最終的な実装の詳細を理解できていません。特に、セクション 4 で導入されたバックトラッキング状態トランスフォーマーです。何らかの理由で、私にはわかりませんが、GHC は、以下の functionに のMonadPlus
インスタンスが必要であると考えています。(ST a)
unify
何が問題なのか、どのように修正すればよいのかわかりません。ここまでは、前の議論とコードを理解したという印象を受けていましたが、どうやら間違っていたようです。誰かが何がうまくいかないのかを指摘できる場合-MonadPlus (ST a)
インスタンスが必要かどうか? - とても参考になります。
[編集: 明確化]著者mzero
は、または のバリエーションmzero
が適切な関数であると主張しているように見えることを指摘しておくべきでした。私は適切な機能が何であるかを知りません。私が疑問に思っているのは、MonadPlus (ST a)
インスタンスを作成することになっているのか、それとも正しい関数を使用していないのか、何かを読み違えてしまったのかということです。
arrays - STArray からの要素の抽出 (解凍と同様)
プログラミング コンテストで Haskell に粒子ベースの流体シミュレーションを実装する際に少し問題があります。現在、各シミュレーション ステップで変更される粒子の配列があります。各粒子は、位置と速度 (私自身の Vec3D モジュール) の 2 つのベクトルのタプルです。ある時点で、粒子から位置を抽出する必要があります (解凍リストのようなもの)。これを次のようにしようとしました。
whereps'
とdoubleDensityRelaxation
はタイプです
xs
タイプのはずですxs :: Array Int Vec3D
。しかし、私は得る
readArray
配列全体を返すことになっていないことを考えると、私が本当に理解していないコンパイラから。たった一つの(Vec3D, Vec3D)
要素。
修正として、直接 doubleDensityRelaxation
取ることはできますか?ST s (STArray s Int Vec3D)
let xs = runSTArray $ do
そのようなタイプを変更して、取得した部分を 削除すると
(ST s xs')
しかし、それを入力として与えると、データコンストラクターがスコープ内にないというxs'
不平を言うだけではありません。ST
私の輸入品は現在
完全な機能:
haskell - この型シグネチャで何が起こっているのでしょうか? (Haskell の Vector.Mutable 修飾子)
Haskell の可変ベクトルには、要素レベルのミューテーターが 3 つあります。
これで問題なく使用できます --
しかし、ここで何が起こっているのでしょうか? とはPrimMonad
? そしてPrimState
コンストラクターですか?
PrimMonad
ここでは、クラスモナドで何らかのバインディングが行われていることを理解しています。thaw
を返しますm (MVector (PrimState m) a)
、どこm
に a PrimMonad
... がありますが、モナドはそれ自体を含んでいますか? m
別のコンテキスト内にあるのはなぜm
ですか?
すべてが基本的に thisPrimState
またはPrimMonad
にバインドされていることがわかりますが、これが変更可能/保存可能なベクトルとどのように関係しているのかわかりません。状態を保存できる型クラスに何か特別なものはありますか?
お時間をいただきありがとうございます!
arrays - 複数の STUArray を使用して返す
ST 計算で複数の STUArray を作成して使用する方法を研究してきました。具体的なシナリオは次のとおりです。
- 複数の配列を作成しますが、そのうちの 1 つだけを返します
- 複数の配列を作成しますが、それらのいずれも返しません
- 複数の配列を作成し、複数の配列を返す
(1)と(2)には答えがありますが、(3)にはありません。
最初にいくつかのインポートを行って、すべてがどこから来ているかを確認します。
(1) の場合、1 つのトリックは、新しいデータ型とコンストラクター関数を定義することです。
配列の 1 つだけを返す方法は次のとおりです。
STRef
(2) の場合、データ構造に を追加し、 で計算を終了し、readSTRef
で実行できますrunST
。
ケース (1) および (2) に対するこのアプローチについてのコメントはありますか? では(3)の場合はどうでしょうか。
haskell - ミュータブル Vector を State Monad に入れる方法
私は Haskell で小さなプログラムを書き、Vector で State Monad を使用して Tree 内の Int 値のすべてのオカレンスをカウントしました。
しかし、不変の Vector の「更新」は O(n) の複雑さで行われます。そして、O(1) での更新と O(1) でのアクセスを探しています。私が理解しているように、可変ベクトルは私が望むことをします。それらを使用するには、ST または IO を使用する必要があります。私はいくつかの UnitTests を実行したいので、ST モナドを好みますが、関数呼び出しでそのベクトルを渡す必要はありません。ErrorT や WriterT などのトランスフォーマーを追加するので、Monad Transformers を使い続ける必要があります。
質問: Monad Transformers を使用して Mutable Vector を State Monad に入れる方法は?
コンパイルできない次のコードを思いつきました。
コンパイル エラーは次のとおりです。
注:境界をチェックしていないことは承知しています。
haskell - 可変グラフでの非同時メッセージ パッシングに Monad/ST を使用する
次の状況のデータ構造を考え出そうとしています。
グラフ構造
重み付けされていない有向エッジを持つノードのグラフを作成する予定です。Graph = [Node]
各ノードには次のものがあります。
- いくつかの TBD 内部 (永続的) 状態
- 着信メッセージのキュー
- 現在のノード状態を受け入れる関数によって決定される、送信できるメッセージのタイプ (失敗の可能性あり)
- エッジのリスト
Node { nodeState :: NodeState, inbox :: Queue NodeMessage, nodeMessage :: (NodeState -> Maybe NodeMessage), connections::[NodeEdge] }
各エッジは、ターゲット ノードの保留中のメッセージをキャプチャする中間ステップです。
NodeEdge { pendingMessage:: Maybe NodeMessage, targetNode :: Node }
メッセージパッシング
メッセージの受け渡しは段階的に発生し、同時ではありません (ただし、計算時間を短縮するためにキューを並行して処理することはできます)。
- フェーズ 1: すべてのノードの受信トレイを確認し、メッセージを処理し
NodeState
、関連する場合は更新します。 - フェーズ 2: すべてのノードを実行
nodeMessage
し、結果が の場合はJust NodeMessage
、すべての接続に NodeMessage を送信します ([NodeEdge]
) - フェーズ 3: すべてのノード エッジをチェックし、メッセージがある場合は、それをターゲット ノードのメッセージ キューに追加します。
モナト/ST
私の最初の計画は、すべてのノードに ID (おそらく単純な Int) を割り当て、各ノードを Map Int Node に格納することでした。ST Monad は試したことがありませんが、 のようなものが使えると思いましST s (M.Map Int Node)
た。任意のフェーズで、各ノードのメッセージ送信アクティビティは O(k log N) で処理できます。
一方、ノード/エッジがエッジ/ノードの変更可能な状態を更新できた場合、任意の単一のキューを O(k) で処理できます。
ST/Map メソッドはかなり直観的に見えますが、グラフ全体を変更可能にすることは私には理解できません。
提案/ヒント/推奨読書はありますか?
haskell - IO と ST Monad の混合 - 「型変数 `s2' はそのスコープをエスケープします」
どのような条件でエラーが発生したかを確認するために、コードを単純化することにしました。ST s (STArray s x y)
次のような単純なネストされた「s」から始めます。
状態コードをテストするために、次の変換を実行します。
状態を維持したまま状態から値を抽出したいので、次のステップは Bool 値を抽出することです。
その Bool を抽出するには、 を使用する必要がありますrunST
。私の理解では、これにより追加の状態が作成されます。これはforall s.
、戻り値の型にa を指定することで指定します。
上記の例はファイナルなしでコンパイルされますforall
が、デバッグしようとしている状況ではこれは不可能です。とにかく、この場合、どちらの方法でもコンパイルされます。
上記のコードを使用して、状態の複数の使用を一緒に連鎖させることができます。
今、私は IO をミックスに投入しようとしているので、適用可能な fmap を利用しています<$>
。これはコンパイルされません: (NB. または を使用した場合と同じfmap
問題)>>= return
<$>
次のエラーが発生します。
ST関数の構成に関するこのSOの質問から、STのすべての可能な用途がコンパイラによって説明されているわけではないことを認識しています。この仮定をテストするために、上記の関数を変更して IO を使用せず、戻り値をラムダに渡すだけにしました。
予想通り、これも同じエラー メッセージでコンパイルされません。
これには課題があります。深くネストされた一連の ST 操作と対話する必要がある IO の妥当な量があります。1 回の繰り返しでは問題なく動作しますが、戻り値をさらに利用することはできません。
arrays - このアルゴリズムを改善するには、1) 配列を使用し、2) リストの連結を回避します (遅延リスト?)。
STArray がどのように機能するかを学ぼうとしましたが、できませんでした。(Docは貧弱です、または少なくとも私が見つけたものです)。
いずれにせよ、次のアルゴリズムがありますが、多くの !! を使用しており、遅いです。STArrayモナドを使用するように変換するにはどうすればよいですか?
編集
おっと、!! 問題ではありませんでした。アルゴリズムの次のバージョン (以下) では、!!; の使用を削除しました。また、@pedrorodriguesが指摘したように、1が素数ではないことを修正しました
今、この質問は実際には約2つの質問です:
1.- リストの代わりに配列を使用するようにこのアルゴリズムを変換する方法は? (Haskellで状態と配列を処理する方法を学ぶためのものです)コメントで誰かがすでに答えていますが、あまりよく説明されていない例を指しています。
2.- 新しい素数が見つかるたびにリストの連結をなくすには?
True -> primesAcum++[現在]