-- SPDX-License-Identifier: MPL-2.0

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

Interpreters for the [coroutine]("Data.Effect.Coroutine") effect.
-}
module Control.Monad.Hefty.Coroutine (
    module Control.Monad.Hefty.Coroutine,
    module Data.Effect.Coroutine,
    module Data.Effect.Input,
    module Data.Effect.Output,
)
where

import Control.Monad.Hefty (Eff, interpretBy, type (~>))
import Data.Effect.Coroutine
import Data.Effect.Input
import Data.Effect.Output

-- | Interpret the [coroutine]("Data.Effect.Coroutine")'s t'Yield' effect.
runCoroutine
    :: forall a b ans ef
     . Eff '[] (Yield a b ': ef) ans
    -> Eff '[] ef (Status (Eff '[] ef) a b ans)
runCoroutine :: forall a b ans (ef :: [* -> *]).
Eff '[] (Yield a b : ef) ans
-> Eff '[] ef (Status (Eff '[] ef) a b ans)
runCoroutine = (ans -> Eff '[] ef (Status (Eff '[] ef) a b ans))
-> Interpreter
     (Yield a b) (Eff '[] ef) (Status (Eff '[] ef) a b ans)
-> Eff '[] (Yield a b : ef) ans
-> Eff '[] ef (Status (Eff '[] ef) a b ans)
forall (e :: * -> *) (ef :: [* -> *]) ans a.
(a -> Eff '[] ef ans)
-> Interpreter e (Eff '[] ef) ans
-> Eff '[] (e : ef) a
-> Eff '[] ef ans
interpretBy (Status (Eff '[] ef) a b ans
-> Eff '[] ef (Status (Eff '[] ef) a b ans)
forall a. a -> Eff '[] ef a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Status (Eff '[] ef) a b ans
 -> Eff '[] ef (Status (Eff '[] ef) a b ans))
-> (ans -> Status (Eff '[] ef) a b ans)
-> ans
-> Eff '[] ef (Status (Eff '[] ef) a b ans)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ans -> Status (Eff '[] ef) a b ans
forall (f :: * -> *) a b r. r -> Status f a b r
Done) (\(Yield a
a) x -> Eff '[] ef (Status (Eff '[] ef) a b ans)
k -> Status (Eff '[] ef) a b ans
-> Eff '[] ef (Status (Eff '[] ef) a b ans)
forall a. a -> Eff '[] ef a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Status (Eff '[] ef) a b ans
 -> Eff '[] ef (Status (Eff '[] ef) a b ans))
-> Status (Eff '[] ef) a b ans
-> Eff '[] ef (Status (Eff '[] ef) a b ans)
forall a b. (a -> b) -> a -> b
$ a
-> (b -> Eff '[] ef (Status (Eff '[] ef) a b ans))
-> Status (Eff '[] ef) a b ans
forall (f :: * -> *) a b r.
a -> (b -> f (Status f a b r)) -> Status f a b r
Continue a
a b -> Eff '[] ef (Status (Eff '[] ef) a b ans)
x -> Eff '[] ef (Status (Eff '[] ef) a b ans)
k)

-- | Converts the t'Input' effect into the [coroutine]("Data.Effect.Coroutine")'s t'Yield' effect.
inputToYield :: Input i ~> Yield () i
inputToYield :: forall i x. Input i x -> Yield () i x
inputToYield Input i x
Input = () -> Yield () i i
forall a b. a -> Yield a b b
Yield ()

-- | Converts the t'Output' effect into the [coroutine]("Data.Effect.Coroutine")'s t'Yield' effect.
outputToYield :: Output o ~> Yield o ()
outputToYield :: forall o x. Output o x -> Yield o () x
outputToYield (Output o
o) = o -> Yield o () ()
forall a b. a -> Yield a b b
Yield o
o