6

私が自分で一緒にジグザグしているものの多くは、実際には私が知らなかった標準の実装を持っているので、誰かが以前にこのタイプのものが使用されたのを見たことがあると言うことができるかどうか興味がありました:

これはモナディック関数を取り、代替によって述語が選択されるまでそれをフォールドし、その後、述語の結果を返します。

until :: (Monad m, Alternative m) => (a -> m a) -> (a -> m c) -> a -> m c
f `until` p = \a -> (f >=> (p `altF` (until f p))) a
  where f1 `altF` f2 = \a -> f1 a <|> f2 a

名前はプレリュードの衝突であることに気づきました。おそらく別の名前を付けますが、私が知らない標準ライブラリに同様の機能がすでにあるかどうかを最初に確認したいと思いました。

また、私が書いた構図の代替案が他の場所で定義されているのか、それともこの機能のいずれかが最初から誤った方向に進んでいるように見えるのか、興味があります。しかし、私の質問の核心は、これは他の場所で実装されているのか、それとも他の場所で非常によく似たものであるのかということです。

4

1 に答える 1

7

プレリュードや標準ライブラリにはない、驚くほど多くの便利な関数がありますが、おそらくそうあるべきです。あなたがそれらが有用であると思うなら、私はいくつかを再実装することについてあまり心配しません。

altFこれはと同等であることに注意してliftA2 (<|>)、次のように記述します。

till :: (Monad m, Alternative m) => (a -> m a) -> (a -> m b) -> a -> m b

-- To do f till p is to first do f; then either p, or f till p.
f `till` p = f >=> (<|>) <$> p <*> f `till` p

(Monad m, Alternative m)そして、それはとほとんど同じであることに注意してMonadPlus m、型を少し単純化することができます:

till :: MonadPlus m => (a -> m a) -> (a -> m b) -> a -> m b
f `till` p = f >=> mplus <$> p <*> f `till` p

Control.Monad.Loopsには、述語を使用する同様の関数がありuntilMControl.Monad.Trans.Loopには任意のループ用のトランスフォーマーがあります。しかし、いいえ、この特定の機能はまだ有名ではないようです。BoolLoopT

于 2013-03-06T09:11:29.287 に答える