Haskell ReaderT IORef的缩放实例

Haskell ReaderT IORef的缩放实例,haskell,monad-transformers,haskell-lens,ioref,Haskell,Monad Transformers,Haskell Lens,Ioref,我是镜头新手,在实现这种类型的变焦实例时遇到问题: newtype MyStateT s m a = MyStateT { unMyStateT :: ReaderT (IORef s) m a } deriving (Functor, Applicative, Monad, MonadIO) instance (MonadIO m) => MonadState s (MyStateT s m) where get = MyStateT $ ReaderT $ l

我是镜头新手,在实现这种类型的变焦实例时遇到问题:

newtype MyStateT s m a = MyStateT
    { unMyStateT :: ReaderT (IORef s) m a
    } deriving (Functor, Applicative, Monad, MonadIO)

instance (MonadIO m) => MonadState s (MyStateT s m) where
    get = MyStateT $ ReaderT $ liftIO . readIORef
    put x = MyStateT $ ReaderT $ \ref -> liftIO $ writeIORef ref x
我一直在尝试使用镜头子状态创建一个新的IORef,在该子状态上运行ReaderT,然后获取更改的子状态并将其替换到主IORef中:

type instance Zoomed (MyStateT s m) = Focusing m
instance (Monad m) => Zoom (MyStateT s m) (MyStateT t m) s t where
    zoom l (MyStateT r) =
        MyStateT $ ReaderT $ \ref -> do
            s <- liftIO $ readIORef ref
            ref' <- liftIO $ newIORef $ s ^. l
            let v = runReader r ref'
            subS' <- liftIO $ readIORef ref'
            let s' = s & l .~ subS'
            liftIO $ writeIORef ref s'
            return v

有人能帮我让这个Zoom实例正常工作吗?谢谢

我的建议是:

type instance Zoomed (MyStateT s m) = Focusing m

instance (MonadIO m) => Zoom (MyStateT s m) (MyStateT t m) s t where
    zoom l (MyStateT r) =
        MyStateT $ ReaderT $ \ref -> do
            s <- liftIO $ readIORef ref
            (v', s') <- unfocusing . flip l s $ \t -> Focusing $ do
                ref' <- liftIO (newIORef t)
                v <- runReaderT r ref'
                t' <- liftIO (readIORef ref')
                return (v, t')
            liftIO $ writeIORef ref s'
            return v'
    {-# INLINE zoom #-}
type实例缩放(MyStateT s m)=m
实例(MonadIO m)=>Zoom(MyStateT s m)(MyStateT m)s t其中
缩放l(我的状态r)=
MyStateT$ReaderT$\ref->do
s
type instance Zoomed (MyStateT s m) = Focusing m

instance (MonadIO m) => Zoom (MyStateT s m) (MyStateT t m) s t where
    zoom l (MyStateT r) =
        MyStateT $ ReaderT $ \ref -> do
            s <- liftIO $ readIORef ref
            (v', s') <- unfocusing . flip l s $ \t -> Focusing $ do
                ref' <- liftIO (newIORef t)
                v <- runReaderT r ref'
                t' <- liftIO (readIORef ref')
                return (v, t')
            liftIO $ writeIORef ref s'
            return v'
    {-# INLINE zoom #-}