4

私は理解を得るためにコードを作成しています。実際には、ソリティア ソルバーです。私は State モナドを使用する単純な力ずくの実装を持っています。実際には、それを使用できることを証明するためです (評価された各移動のカウントを保持するだけです)。しかし今、Unboxed Mutable 配列を使用して訪問したボードを記録し、別のパスを介して既に訪問したボードの位置に到達したときにパスの評価を短縮したいと考えています。ST モナドでは暗黙の状態をスレッド化できないようですが、Mutable 配列にアクセスするには ST (または IO) を使用する必要があります。だから私は2つのモナドを組み合わせる必要があるようです - 状態をスレッド化する状態(実際にはミュータブル配列を含みます)とミュータブル配列関数を得る別のモナド(ST)。

  • これは正しいですか?
  • もしそうなら、(標準的な?) Data.Array.ST/Control.Monad.ST/Control.Monad.ST と mtl の組み合わせよりも優れた代替手段はありますか?
  • もし私がこの方法をとった場合、ST と State をどの順序でスタックするかは重要ですか?
  • モナドトランスフォーマーの使用を避けるために、ST または State のいずれかまたは両方に基づいて独自の単一のモナドをローリングすることを検討する必要がありますか?
4

2 に答える 2

5

を使用する場合ST、あなたが持っている配列または参照は、言葉のモナドの意味で実際には状態ではありません: それらは決して変更されません! Stateそれらはポインターと考えることができます。ポインターは一定ですが、ポインターが指すものは変わる可能性があります。したがって、配列や参照などSTを関数の引数としてアクションに渡すことができます。アクションが渡されたものとは異なる配列を返す必要があると予想される場合、つまり、既存の配列を変更するだけでなく、新しい配列を作成する必要がある場合、このStateT機構は適切です。これは一般的に当てはまらないため、適切ではありません。STStateT

モナドトランスフォーマースタックが本当に必要な場合は、配列と参照をモナドの環境に置くことができますReaderT。しかし、これはおそらく必要ありません。

于 2014-02-20T22:48:08.163 に答える