簡體   English   中英

抬起以固定monad變壓器堆棧的* inside *

[英]Lift to fix the *inside* of a monad transformer stack

假設我有一個包含在StateT MyStateIO Int ,那么我有一個State MyState Int的值,我想在堆疊monad中使用它。 如何在這種內在意義上解除它? 我已經知道使用liftliftIO如果我得到一些與我需要提升到外部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如果我可以避免它。

您有兩種選擇:

  1. 找一個monad態射。 這通常是找到合適的圖書館的問題; 在這種情況下, 提升概括在一起應該讓你到達你需要去的地方。
  2. 使你的State行動更具多態性。 這是常用的,推薦的; 它相當於預先應用第1部分中的態射,但是在mtl庫中已經有很多機器可以使它變得容易。 這里的想法是,如果你只是根據getputmodify來編寫你的State動作,那么你可以給它類型:而不是類型State sa

     MonadState sm => ma 

    然后,在調用站點,您可以選擇適合此的monad,包括State saStateT s IO a 此外,由於它專門用於類型State sa ,你可以確定它不會做任何IO或類似的State sa本身不能做的事情,所以你得到相同的行為保證。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM