2012-02-23 40 views
2

我在程序中的不同級別的控制結構有兩種類型的聲明。最下面的是AgentStateTIO的功能。第二個是另一個StateTAgent的功能,第三個(Plan)是ErrorT如何很好地評估嵌套的StateT和ErrorT monads?

type Agent = StateT AgentState IO 
type Plan = ErrorT PlanError (StateT PlanState Agent) 

什麼是評價一個Plan的最佳方式?我寫了下面的代碼,但它不是很少,因爲有嵌套的runStateTrunErrorT調用負載。

foo :: Plan() 
defaultAgentState :: AgentState 
runStateT (runStateT (runErrorT foo) (PlanState 0)) defaultAgentState 

有什麼更簡單/更好嗎?

+0

你可以定義一個'runPlan'函數,所以你只需要堆棧一次,而不是每次調用它。 – 2012-02-23 15:25:19

+0

但是'runPlan'的定義就像我的最後一個表達式一樣,它將'runStateT'和'runErrorT'放在一起,對吧?一般來說沒有捷徑,如果我有一堆monad變換器來運行它們,我必須疊放適量的'runXyzT'。 對於可能愚蠢的問題,我很抱歉,但我對MTL很陌生,但我覺得它仍然有點困難。 – 2012-02-23 15:40:58

+1

對。在某個地方,每個'runXyzT'都必須被調用,這是沒有辦法的。但是在一個地方就足夠了,所以如果你執行很多'Plan',你不需要每次重複堆棧。順便提一下,這個問題絕對不是愚蠢的。 – 2012-02-23 15:44:59

回答

5

如果你有一個monad變壓器堆棧,每個變壓器的runXyzT函數都必須在某個時候調用,但不幸的是沒有捷徑。

但是,如果您不止一次使用特定堆棧,那麼定義一個特殊的函數是值得的,因此堆疊的runXyzT的混亂只出現在一個點上。