From de4ba37da1d5f62de5e45921b5e11a00b9bfc08b Mon Sep 17 00:00:00 2001
From: Jens Nolte <git@queezle.net>
Date: Wed, 1 Sep 2021 00:13:52 +0200
Subject: [PATCH] Add documentation

---
 src/Quasar/Awaitable.hs | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/src/Quasar/Awaitable.hs b/src/Quasar/Awaitable.hs
index 755aa98..acf4d24 100644
--- a/src/Quasar/Awaitable.hs
+++ b/src/Quasar/Awaitable.hs
@@ -18,9 +18,9 @@ module Quasar.Awaitable (
   awaitSuccessOrFailure,
 
   -- ** Awaiting multiple awaitables
-  awaitEither,
   awaitAny,
   awaitAny2,
+  awaitEither,
 
   -- * AsyncVar
   AsyncVar,
@@ -60,6 +60,7 @@ import Quasar.Prelude
 
 
 class (MonadCatch m, MonadPlus m) => MonadAwait m where
+  -- | Wait until an awaitable is completed and then return it's value (or throw an exception).
   await :: IsAwaitable r a => a -> m r
 
   -- | Await an `STM` transaction. The STM transaction must always return the same result and should not have visible
@@ -93,6 +94,11 @@ peekAwaitable awaitable = liftIO $ runMaybeT $ runQueryT queryFn (runAwaitable a
 
 
 class IsAwaitable r a | a -> r where
+  -- | Run the awaitable. You probably want to use `await` instead, `runAwaitable` is exposed to implement an instance
+  -- of `IsAwaitable`.
+  --
+  -- The implementation of `async` calls `runAwaitable` in most monads, so the implementation of `runAwaitable` must
+  -- not call `async` without deconstructing first.
   runAwaitable :: (MonadAwait m) => a -> m r
   runAwaitable self = runAwaitable (toAwaitable self)
 
@@ -336,7 +342,7 @@ putAsyncVarEitherSTM_ var = void . putAsyncVarEitherSTM var
 
 -- * Utility functions
 
--- | Create an awaitable that is completed successfully when the input awaitable is successful or failed.
+-- | Await success or failure of another awaitable, then return `()`.
 awaitSuccessOrFailure :: (IsAwaitable r a, MonadAwait m) => a -> m ()
 awaitSuccessOrFailure = await . fireAndForget . toAwaitable
   where
@@ -346,7 +352,7 @@ awaitSuccessOrFailure = await . fireAndForget . toAwaitable
 -- ** Awaiting multiple awaitables
 
 
-
+-- | Completes as soon as either awaitable completes.
 awaitEither :: (IsAwaitable ra a, IsAwaitable rb b, MonadAwait m) => a -> b -> m (Either ra rb)
 awaitEither x y = mkMonadicAwaitable $ stepBoth (runAwaitable x) (runAwaitable y)
   where
@@ -360,7 +366,13 @@ awaitEither x y = mkMonadicAwaitable $ stepBoth (runAwaitable x) (runAwaitable y
         Left resultX -> stepBoth (nextX resultX) stepY
         Right resultY -> stepBoth stepX (nextY resultY)
 
+-- | Helper for `awaitEither`
+eitherSTM :: STM a -> STM b -> STM (Either a b)
+eitherSTM x y = fmap Left x `orElse` fmap Right y
+
 
+-- Completes as soon as any awaitable in the list is completed and then returns the left-most completed result
+-- (or exception).
 awaitAny :: (IsAwaitable r a, MonadAwait m) => NonEmpty a -> m r
 awaitAny xs = mkMonadicAwaitable $ stepAll Empty Empty $ runAwaitable <$> fromList (toList xs)
   where
@@ -381,13 +393,11 @@ awaitAny xs = mkMonadicAwaitable $ stepAll Empty Empty $ runAwaitable <$> fromLi
       newAwaitableSteps <- unsafeAwaitSTM $ maybe impossibleCodePathM anySTM $ nonEmpty (toList acc)
       stepAll Empty Empty newAwaitableSteps
 
+-- | Helper for `awaitAny`
+anySTM :: NonEmpty (STM a) -> STM a
+anySTM (x :| xs) = x `orElse` maybe retry anySTM (nonEmpty xs)
 
+
+-- | Like `awaitAny` with two awaitables.
 awaitAny2 :: (IsAwaitable r a, MonadAwait m) => a -> a -> m r
 awaitAny2 x y = awaitAny (x :| [y])
-
-
-eitherSTM :: STM a -> STM b -> STM (Either a b)
-eitherSTM x y = fmap Left x `orElse` fmap Right y
-
-anySTM :: NonEmpty (STM a) -> STM a
-anySTM (x :| xs) = x `orElse` maybe retry anySTM (nonEmpty xs)
-- 
GitLab