From b68ca45e7c443b4514dbb82634dcb5cc523a2b61 Mon Sep 17 00:00:00 2001
From: Jens Nolte <git@queezle.net>
Date: Mon, 4 Oct 2021 15:03:09 +0200
Subject: [PATCH] Add afix function (like mfix, but the value is passed as an
 awaitable)

---
 src/Quasar/Awaitable.hs | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/Quasar/Awaitable.hs b/src/Quasar/Awaitable.hs
index 4a07aed..47ff577 100644
--- a/src/Quasar/Awaitable.hs
+++ b/src/Quasar/Awaitable.hs
@@ -13,7 +13,8 @@ module Quasar.Awaitable (
   awaitableFromSTM,
 
   -- * Awaitable helpers
-
+  afix,
+  afix_,
   awaitSuccessOrFailure,
 
   -- ** Awaiting multiple awaitables
@@ -370,6 +371,22 @@ awaitSuccessOrFailure = await . fireAndForget . toAwaitable
     fireAndForget :: MonadCatch m => m r -> m ()
     fireAndForget x = void x `catchAll` const (pure ())
 
+afix :: (MonadIO m, MonadCatch m) => (Awaitable a -> m a) -> m a
+afix action = do
+  var <- newAsyncVar
+  catchAll
+    do
+      result <- action (toAwaitable var)
+      putAsyncVar_ var result
+      pure result
+    \ex -> do
+      failAsyncVar_ var ex
+      throwM ex
+
+afix_ :: (MonadIO m, MonadCatch m) => (Awaitable a -> m a) -> m ()
+afix_ = void . afix
+
+
 -- ** Awaiting multiple awaitables
 
 
-- 
GitLab