2013-03-06 8 views
6

Ich finde eine Menge Dinge, die ich selbst zusammengerüttelt habe, die überhaupt nützlich scheinen, haben eine Standardimplementierung, von der ich gerade nichts wusste, also war neugierig, wenn irgendjemand sagen könnte, dass sie diese Art von früher verwendetem Ding gesehen haben :Ist diese Haskell-Funktion als anderer Name bekannt/implementiert?

es hat eine einstellige Funktion nimmt und es wird klappen, bis ein Prädikat durch Alternative gewählt wird, dann gibt sie das Ergebnis des Prädikats:

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 

ich den Namen erkennen, ein Vorspiel Kollision ist, werde ich wahrscheinlich Nennen Sie es etwas anderes, aber ich dachte, ich würde zuerst sehen, ob es bereits eine ähnliche Funktionalität in einer Standardbibliothek gibt, von der ich nichts weiß.

Ich denke auch, ich bin neugierig, wenn die kompositorische Alternative, die ich geschrieben habe, woanders definiert ist oder wenn etwas von dieser Funktionalität irrtümlich erscheint. Aber der Kernpunkt meiner Frage ist, ist dies anderswo implementiert oder ist etwas sehr ähnlich umgesetzt woanders

+0

Möglicherweise möchten Sie 'MonadPlus' anstelle der kombinierten 'Monad'- und' Alternative'-Einschränkungen verwenden. –

+0

@pelotom Sie können Alternative in Bezug auf MonadPlus definieren? Ich war mir nicht bewusst, ich nahm meine Unterschrift direkt aus GHCi –

+1

Sie definieren verschiedene APIs, aber führen ähnliche Rollen aus ... 'Alternative':' Applicative' :: 'MonadPlus':' Monad'. –

Antwort

7

Es gibt eine überraschend große Anzahl von Komfort-Funktionen, die nicht in der Prelude oder Standard-Bibliotheken sind, aber vielleicht sollte. Ich würde mir nicht zu viel Sorgen machen, wenn ich ein paar neu implementiere, wenn Sie sie nützlich finden.

Anbetracht dessen, dass altF zu liftA2 (<|>) entspricht, können Sie es wie folgt schreiben:

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 

Und stellt fest, dass (Monad m, Alternative m) ist sehr ähnlich wie MonadPlus m Sie die Art ein wenig vereinfachen kann:

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

Es gibt eine ähnliche Funktion namens untilM in Control.Monad.Loops, die ein Bool Prädikat verwendet, und ein LoopT Transformator e Xists für beliebige Schleifen in Control.Monad.Trans.Loop. Aber nein, diese besondere Funktion scheint noch nicht berühmt zu sein.

Verwandte Themen