-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later

module Utils.Memo
  ( evalMemoStateC
  ) where

import ClassyPrelude
import Data.Conduit
import Data.Conduit.Lift (evalStateC)

import Control.Monad.Memo
import Control.Monad.Trans.State.Strict (StateT)
import qualified Control.Monad.State.Class as State


evalMemoStateC :: forall m s k v i o r.
                  Monad m
               => s -> ConduitT i o (MemoStateT s k v m) r -> ConduitT i o m r
evalMemoStateC initSt = evalStateC initSt . transPipe runMemoStateT'
  where
    runMemoStateT' :: forall a.
                      MemoStateT s k v m a
                   -> StateT s m a
    runMemoStateT' act = do
          cache <- State.get
          (res, cache') <- lift $ runMemoStateT act cache
          res <$ State.put cache'
