這個問題顯然與討論的問題here和here有關。不幸的是,我的要求與這些問題略有不同,所給出的答案不適用於我。我也不太明白爲什麼runST
未能在這些情況下輸入檢查,這沒有幫助。在變壓器堆棧中展開STT monad?
我的問題是這樣的,我有一個代碼段使用一個單子堆棧,或者更確切地說,一個單子:
import Control.Monad.Except
type KErr a = Except KindError a
的另一段代碼需要與此一個包裝這個STT monad內集成:
type RunM s a = STT s (Except KindError) a
在這些部分之間的接口處,我顯然需要包裝和解開外層。我有以下功能在KErr
工作 - >RunM
方向:
kerrToRun :: KErr a -> RunM s a
kerrToRun e = either throwError return $ runExcept e
,但由於某種原因,我只是不能反過來鍵入查詢:
runToKErr :: RunM s a -> KErr a
runToKErr r = runST r
我假設RunM
的內部monad具有與KErr
相同的結構,我可以在解開STT
圖層後返回它,但我似乎無法獲得如此遠的效果,因爲runST
抱怨關於其類型參數:
src/KindLang/Runtime/Eval.hs:18:21:
Couldn't match type ‘s’ with ‘s1’
‘s’ is a rigid type variable bound by
the type signature for runToKErr :: RunM s a -> KErr a
at src/KindLang/Runtime/Eval.hs:17:14
‘s1’ is a rigid type variable bound by
a type expected by the context:
STT s1 (ExceptT KindError Data.Functor.Identity.Identity) a
at src/KindLang/Runtime/Eval.hs:18:15
Expected type: STT
s1 (ExceptT KindError Data.Functor.Identity.Identity) a
Actual type: RunM s a
我也試過:
runToKErr r = either throwError return $ runExcept $ runST r
,以更強烈隔離其預期收益類型runST
,在那是問題的原因的情況下,但結果是一樣的。
這個s1
類型從哪裏來,我如何說服ghc它與s
是同一類型?