[英]Lift to fix the *inside* of a monad transformer stack
假設我有一個包含在StateT MyState
的IO Int
,那么我有一個State MyState Int
的值,我想在堆疊monad中使用它。 如何在這種內在意義上解除它? 我已經知道使用lift
或liftIO
如果我得到一些與我需要提升到外部monad的內部兼容的東西,但現在我有相反的問題:值已經在外部monad但不是內部monad。
例如:
checkSame :: State MyState a -> IO a -> StateT MyState IO Bool
checkSame sim real = do
rres <- liftIO real
sres <- ??? sim
return $ rres == sres
我是否必須“獲取”狀態,手動將其推入runState並將其全部重新裝箱,或者是否有一些通用的方法來執行此操作?
順便說一句,那個sim參數是一大堆與IO無關的有狀態函數,所以我有點不願意讓它們全部返回StateT MyState IO a
如果我可以避免它。
您有兩種選擇:
使你的State
行動更具多態性。 這是常用的,推薦的; 它相當於預先應用第1部分中的態射,但是在mtl
庫中已經有很多機器可以使它變得容易。 這里的想法是,如果你只是根據get
, put
和modify
來編寫你的State
動作,那么你可以給它類型:而不是類型State sa
。
MonadState sm => ma
然后,在調用站點,您可以選擇適合此的monad,包括State sa
和StateT s IO a
。 此外,由於它專門用於類型State sa
,你可以確定它不會做任何IO
或類似的State sa
本身不能做的事情,所以你得到相同的行為保證。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.