-- |
-- Copyright: (C) 2016 Tweag I/O Limited.

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Control.Monad.R.Internal where

import Control.Memory.Region
import Control.Monad.R.Class
import Data.Proxy (Proxy(..))
import Data.Reflection (Reifies, reify)
import Foreign.R (SEXP)

newtype AcquireIO s = AcquireIO (forall ty. SEXP V ty -> IO (SEXP s ty))

withAcquire
  :: forall m r.
     (MonadR m)
  => (forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
  -> m r
withAcquire :: forall (m :: * -> *) r.
MonadR m =>
(forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r)
-> m r
withAcquire forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r
f = do
    ExecContext m
cxt <- forall (m :: * -> *). MonadR m => m (ExecContext m)
getExecContext
    forall a r. a -> (forall s. Reifies s a => Proxy s -> r) -> r
reify (forall s.
(forall (ty :: SEXPTYPE). SEXP V ty -> IO (SEXP s ty))
-> AcquireIO s
AcquireIO (\SEXP V ty
sx -> forall (m :: * -> *) a. MonadR m => m a -> ExecContext m -> IO a
unsafeRunWithExecContext (forall (m :: * -> *) s (a :: SEXPTYPE).
(MonadR m, s ~ V) =>
SEXP s a -> m (SEXP (Region m) a)
acquire SEXP V ty
sx) ExecContext m
cxt)) forall s. Reifies s (AcquireIO (Region m)) => Proxy s -> m r
f