@zth
bs-let works. But in rescript syntax the ppx syntax nests the calls anyway (so no use in using it).
For example (probably not the best example, but from a random file in my project):
Reason Syntax
        let%AwaitThen _ =
          HelperActions.mintDirect(
            ~marketIndex,
            ~amount=initialAmountShort,
            ~token=paymentToken,
            ~user=testUser,
            ~longShort,
            ~oracleManagerMock=oracleManager,
            ~isLong=false,
          );
        let pricesBelow = Belt.Array.makeBy(numberOfItems - 1, i => i);
        let%AwaitThen (_, resultsBelow) =
          pricesBelow->Array.reduce(
            (initialPrice, [||])->JsPromise.resolve,
            (lastPromise, _) => {
              let%AwaitThen (lastPrice, results) = lastPromise;
              let newPrice = lastPrice->sub(CONSTANTS.tenToThe18);
              let%AwaitThen _ =
                oracleManager->OracleManagerMock.setPrice(~newPrice);
              let%AwaitThen _ =
                longShort->LongShort.updateSystemState(~marketIndex);
              let%AwaitThen shortValue =
                longShort->LongShort.syntheticTokenPoolValue(
                  marketIndex,
                  false/*short*/,
                );
              let%AwaitThen longValue =
                longShort->LongShort.syntheticTokenPoolValue(
                  marketIndex,
                  true/*long*/,
                );
              (
                newPrice,
                [|
                  (
                    newPrice->Ethers.Utils.formatEther,
                    shortValue->Ethers.Utils.formatEther,
                    longValue->Ethers.Utils.formatEther,
                  ),
                |]
                ->Array.concat(results),
              )
              ->JsPromise.resolve;
            },
          );
        prices :=
          prices.contents
          ->Array.concat(resultsBelow)
          ->Array.concat([|
              (
                initialPrice->Ethers.Utils.formatEther,
                initialAmountShort->Ethers.Utils.formatEther,
                initialAmountLong->Ethers.Utils.formatEther,
              ),
            |]);
        ()->JsPromise.resolve;
Turns into the following rescript:
      %AwaitThen({
        let _ = HelperActions.mintDirect(
          ~marketIndex,
          ~amount=initialAmountShort,
          ~token=paymentToken,
          ~user=testUser,
          ~longShort,
          ~oracleManagerMock=oracleManager,
          ~isLong=false,
        )
        let pricesBelow = Belt.Array.makeBy(numberOfItems - 1, i => i)
        %AwaitThen({
          let (_, resultsBelow) = pricesBelow->Array.reduce((initialPrice, [])->JsPromise.resolve, (
            lastPromise,
            _,
          ) =>
            %AwaitThen({
              let (lastPrice, results) = lastPromise
              let newPrice = lastPrice->sub(CONSTANTS.tenToThe18)
              %AwaitThen({
                let _ = oracleManager->OracleManagerMock.setPrice(~newPrice)
                %AwaitThen({
                  let _ = longShort->LongShort.updateSystemState(~marketIndex)
                  %AwaitThen({
                    let shortValue =
                      longShort->LongShort.syntheticTokenPoolValue(marketIndex, false /* short */)
                    %AwaitThen({
                      let longValue =
                        longShort->LongShort.syntheticTokenPoolValue(marketIndex, true /* long */)
                      (
                        newPrice,
                        [
                          (
                            newPrice->Ethers.Utils.formatEther,
                            shortValue->Ethers.Utils.formatEther,
                            longValue->Ethers.Utils.formatEther,
                          ),
                        ]->Array.concat(results),
                      )->JsPromise.resolve
                    })
                  })
                })
              })
            })
          )
          prices :=
            prices.contents
            ->Array.concat(resultsBelow)
            ->Array.concat([
              (
                initialPrice->Ethers.Utils.formatEther,
                initialAmountShort->Ethers.Utils.formatEther,
                initialAmountLong->Ethers.Utils.formatEther,
              ),
            ])
          ()->JsPromise.resolve
        })
      })