-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/.

{- |
Copyright   :  (c) 2023 Yamada Ryo
License     :  MPL-2.0 (see the file LICENSE)
Maintainer  :  ymdfield@outlook.jp
Stability   :  experimental
Portability :  portable

Elaborator for the t'Control.Effect.Class.Provider.Implicit.ImplicitProvider' effect class.
-}
module Control.Effect.Interpreter.Heftia.Provider.Implicit where

import Control.Effect (type (~>))
import Control.Effect.Hefty (Eff, Elab, raise)
import Control.Effect.Interpreter.Heftia.Reader (runAsk)
import Control.Freer (Freer)
import Data.Effect.HFunctor (HFunctor)
import Data.Effect.Provider.Implicit (ImplicitProvider' (WithImplicit))
import Data.Effect.Reader (LAsk)
import Data.Hefty.Union (Union)

-- | Elaborate the t'ImplicitProvider'' effect using the given interpreter.
elaborateImplicitProvider ::
    (c g, e g) =>
    (f ~> g) ->
    (i -> forall x. g x -> f x) ->
    Elab (ImplicitProvider' c i e) f
elaborateImplicitProvider :: forall (c :: (* -> *) -> Constraint) (g :: * -> *)
       (e :: (* -> *) -> Constraint) (f :: * -> *) i.
(c g, e g) =>
(f ~> g)
-> (i -> forall x. g x -> f x) -> Elab (ImplicitProvider' c i e) f
elaborateImplicitProvider f ~> g
iLower i -> forall x. g x -> f x
run (WithImplicit i
i forall (g :: * -> *). (c g, e g) => (forall x. f x -> g x) -> g x
f) = i -> forall x. g x -> f x
run i
i forall a b. (a -> b) -> a -> b
$ forall (g :: * -> *). (c g, e g) => (forall x. f x -> g x) -> g x
f f ~> g
iLower
{-# INLINE elaborateImplicitProvider #-}

runImplicitProvider ::
    ( e (Eff u fr eh (LAsk i ': ef))
    , c (Eff u fr eh (LAsk i ': ef))
    , Freer c fr
    , Union u
    , HFunctor (u eh)
    , Applicative (Eff u fr eh ef)
    ) =>
    Elab (ImplicitProvider' c i e) (Eff u fr eh ef)
runImplicitProvider :: forall (e :: (* -> *) -> Constraint) (u :: [SigClass] -> SigClass)
       (fr :: SigClass) (eh :: [SigClass]) i (ef :: [SigClass])
       (c :: (* -> *) -> Constraint).
(e (Eff u fr eh (LAsk i : ef)), c (Eff u fr eh (LAsk i : ef)),
 Freer c fr, Union u, HFunctor (u eh),
 Applicative (Eff u fr eh ef)) =>
Elab (ImplicitProvider' c i e) (Eff u fr eh ef)
runImplicitProvider (WithImplicit i
i forall (g :: * -> *).
(c g, e g) =>
(forall x. Eff u fr eh ef x -> g x) -> g x
f) = forall r (rs :: [SigClass]) (eh :: [SigClass]) (fr :: SigClass)
       (u :: [SigClass] -> SigClass) (c :: (* -> *) -> Constraint).
(Freer c fr, Union u, Applicative (Eff u fr eh rs),
 HFunctor (u eh)) =>
r -> Eff u fr eh (LAsk r : rs) ~> Eff u fr eh rs
runAsk i
i forall a b. (a -> b) -> a -> b
$ forall (g :: * -> *).
(c g, e g) =>
(forall x. Eff u fr eh ef x -> g x) -> g x
f forall (e :: SigClass) (r :: [SigClass]) (ehs :: [SigClass])
       (fr :: SigClass) (u :: [SigClass] -> SigClass)
       (c :: (* -> *) -> Constraint).
(Freer c fr, Union u, HFunctor (u ehs)) =>
Eff u fr ehs r ~> Eff u fr ehs (e : r)
raise
{-# INLINE runImplicitProvider #-}