{-# LANGUAGE CPP #-}

-- SPDX-License-Identifier: MPL-2.0

{- |
Copyright   :  (c) 2024 Sayo contributors
License     :  MPL-2.0 (see the LICENSE file)
Maintainer  :  ymdfield@outlook.jp

Interpreters for the [Parallel]("Data.Effect.Concurrent.Parallel") effects.
-}
module Control.Monad.Hefty.Concurrent.Parallel (
    module Control.Monad.Hefty.Concurrent.Parallel,
    module Data.Effect.Concurrent.Parallel,
    module Data.Effect.Input,
)
where

#if ( __GLASGOW_HASKELL__ < 906 )
import Control.Applicative (liftA2)
#endif
import Control.Effect.Transform (onlyFOEs)
import Control.Monad.Hefty (Eff, transform, (:>))
import Control.Monad.Hefty.Coroutine (inputToYield, runCoroutine)
import Data.Effect.Concurrent.Parallel
import Data.Effect.Coroutine (Status (Continue, Done))
import Data.Effect.Input
import Data.Effect.OpenUnion (RemoveHOEs, WeakenHOEs)

polling :: (Poll :> es, WeakenHOEs es) => Eff es a -> Eff (Input (Maybe a) ': RemoveHOEs es) b -> Eff es b
polling :: forall (es :: [Effect]) a b.
(Poll :> es, WeakenHOEs es) =>
Eff es a -> Eff (Input (Maybe a) : RemoveHOEs es) b -> Eff es b
polling Eff es a
pollee Eff (Input (Maybe a) : RemoveHOEs es) b
poller =
    (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b
 -> Maybe a
 -> Eff
      Freer
      es
      (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)))
-> Eff Freer es (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
-> Eff es a
-> Eff Freer es b
forall a b r (f :: * -> *) (es :: [Effect]) (ff :: Effect)
       (c :: (* -> *) -> Constraint).
(Free c ff, f ~ Eff ff es, Poll :> es) =>
(a -> Maybe b -> f (Either r a)) -> f a -> f b -> f r
poldl
        ( \case
            Done b
r -> Eff
  Freer
  es
  (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
-> Maybe a
-> Eff
     Freer
     es
     (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
forall a b. a -> b -> a
const (Eff
   Freer
   es
   (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
 -> Maybe a
 -> Eff
      Freer
      es
      (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)))
-> Eff
     Freer
     es
     (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
-> Maybe a
-> Eff
     Freer
     es
     (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
forall a b. (a -> b) -> a -> b
$ Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
-> Eff
     Freer
     es
     (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
forall a. a -> Eff Freer es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
 -> Eff
      Freer
      es
      (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)))
-> Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
-> Eff
     Freer
     es
     (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
forall a b. (a -> b) -> a -> b
$ b -> Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
forall a b. a -> Either a b
Left b
r
            Continue () Maybe a
-> Eff
     Freer
     (RemoveHOEs es)
     (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
k -> (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b
 -> Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
-> Eff Freer es (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
-> Eff
     Freer
     es
     (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
forall a b. (a -> b) -> Eff Freer es a -> Eff Freer es b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b
-> Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
forall a b. b -> Either a b
Right (Eff Freer es (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
 -> Eff
      Freer
      es
      (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)))
-> (Maybe a
    -> Eff
         Freer es (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
-> Maybe a
-> Eff
     Freer
     es
     (Either b (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Eff
  Freer
  (RemoveHOEs es)
  (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
-> Eff Freer es (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
forall (es :: [Effect]) a (ff :: Effect)
       (c :: (* -> *) -> Constraint).
(Free c ff, WeakenHOEs es) =>
Eff ff (RemoveHOEs es) a -> Eff ff es a
onlyFOEs (Eff
   Freer
   (RemoveHOEs es)
   (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
 -> Eff
      Freer es (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
-> (Maybe a
    -> Eff
         Freer
         (RemoveHOEs es)
         (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
-> Maybe a
-> Eff Freer es (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe a
-> Eff
     Freer
     (RemoveHOEs es)
     (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
k
        )
        (Eff
  Freer
  (RemoveHOEs es)
  (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
-> Eff Freer es (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
forall (es :: [Effect]) a (ff :: Effect)
       (c :: (* -> *) -> Constraint).
(Free c ff, WeakenHOEs es) =>
Eff ff (RemoveHOEs es) a -> Eff ff es a
onlyFOEs (Eff
   Freer
   (RemoveHOEs es)
   (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
 -> Eff
      Freer es (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
-> Eff
     Freer
     (RemoveHOEs es)
     (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
-> Eff Freer es (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
forall a b. (a -> b) -> a -> b
$ Eff (Yield () (Maybe a) : RemoveHOEs es) b
-> Eff
     Freer
     (RemoveHOEs es)
     (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
forall ans a b (es :: [Effect]).
FOEs es =>
Eff (Yield a b : es) ans -> Eff es (Status (Eff es) a b ans)
runCoroutine (Eff (Yield () (Maybe a) : RemoveHOEs es) b
 -> Eff
      Freer
      (RemoveHOEs es)
      (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b))
-> Eff (Yield () (Maybe a) : RemoveHOEs es) b
-> Eff
     Freer
     (RemoveHOEs es)
     (Status (Eff Freer (RemoveHOEs es)) () (Maybe a) b)
forall a b. (a -> b) -> a -> b
$ (Input (Maybe a) (Eff Freer (Yield () (Maybe a) : RemoveHOEs es))
 ~> Yield
      () (Maybe a) (Eff Freer (Yield () (Maybe a) : RemoveHOEs es)))
-> Eff (Input (Maybe a) : RemoveHOEs es) b
-> Eff (Yield () (Maybe a) : RemoveHOEs es) b
forall (e :: Effect) (e' :: Effect) (es :: [Effect]) a
       (ff :: Effect) (c :: (* -> *) -> Constraint).
(KnownOrder e, KnownOrder e', Free c ff) =>
(e (Eff ff (e' : es)) ~> e' (Eff ff (e' : es)))
-> Eff ff (e : es) a -> Eff ff (e' : es) a
transform Input (Maybe a) (Eff Freer (Yield () (Maybe a) : RemoveHOEs es)) x
-> Yield
     () (Maybe a) (Eff Freer (Yield () (Maybe a) : RemoveHOEs es)) x
Input (Maybe a) (Eff Freer (Yield () (Maybe a) : RemoveHOEs es))
~> Yield
     () (Maybe a) (Eff Freer (Yield () (Maybe a) : RemoveHOEs es))
forall i (f :: * -> *) a. Input i f a -> Yield () i f a
inputToYield Eff (Input (Maybe a) : RemoveHOEs es) b
poller)
        Eff es a
pollee