首页 > 解决方案 > 捕获由 execStateT 更改的状态

问题描述

我对 Haskell 很陌生。最近,我不得不为我的项目使用它。

我有一段代码正在评估某些状态execStateT,我想捕捉每个状态变化并返回它。

我试图了解什么是 execStateT 和代码流,但我在某些地方失败了,我无法理解如何获得我真正想要的东西。也许由于对 monad 和其他概念的一些原始理解,我发现需要更改代码的整个结构。

在接下来的代码中,我尝试使用par来创建一个文件并将变量的状态写入该文件,因此它不会影响代码的实际工作。但它没有创建文件并将输入写入其中。

我面临以下代码

campaign u v w ts d = let d' = fromMaybe defaultDict d in fmap (fromMaybe mempty) (view (hasLens . to knownCoverage)) >>= \c -> do
  g <- view (hasLens . to seed)
  let g' = mkStdGen $ fromMaybe (d' ^. defSeed) g
  execStateT (evalRandT runCampaign g') (Campaign ((,Open (-1)) <$> ts) c d') where
    step        = runUpdate (updateTest v Nothing) >> lift u >> runCampaign
    runCampaign = use (hasLens . tests . to (fmap snd)) >>= update
    update c    = view hasLens >>= \(CampaignConf tl q sl _ _) ->
      if | any (\case Open  n   -> n < tl; _ -> False) c -> callseq v w q >> step
         | any (\case Large n _ -> n < sl; _ -> False) c -> step
         | otherwise                                     -> lift u

我在这里想要的是找到一些方法来查看变量的变化v,以做我的进一步工作。这可以通过将变量写入文件或将其返回到控制台来完成。

感谢帮助!

[编辑 1]

这是我正在制作的进口商品:

import Control.Lens
import Control.Monad (liftM2, replicateM, when)
import Control.Monad.Catch (MonadCatch(..), MonadThrow(..))
import Control.Monad.Random.Strict (MonadRandom, RandT, evalRandT)
import Control.Monad.Reader.Class (MonadReader)
import Control.Monad.State.Strict (MonadState(..), StateT, evalStateT, execStateT)
import Control.Monad.Trans (lift)
import Control.Monad.Trans.Random.Strict (liftCatch)
import Data.Aeson (ToJSON(..), object)
import Data.Bool (bool)
import Data.Either (lefts)
import Data.Foldable (toList)
import Data.Map (Map, mapKeys, unionWith)
import Data.Maybe (fromMaybe, isNothing, maybeToList)
import Data.Ord (comparing)
import Data.Has (Has(..))
import Data.Set (Set, union)
import Data.Text (unpack)
import EVM
import EVM.Types (W256)
import Numeric (showHex)
import System.Random (mkStdGen)

标签: haskellfunctional-programmingstatehaskell-stack

解决方案


这是一种方法。假设你有一个单子类,它支持记录某种类型的消息(MonadLogger是一个,但我对它的了解不够,无法在这里使用它)。我将只使用一个假设的CanLog类。现在你可以写

newtype LStateT s m a = LStateT
  {runLStateT :: StateT s m a}
  deriving (Functor, Applicative, Monad)

instance CanLog s m => MonadState s (LStateT s m) where
   get = LStateT get
   put x = LStateT $ do
     lift $ -- Log the state transition
     put x

推荐阅读