考慮下面的代碼片斷任意單子變壓器堆棧變量
import Control.Monad.Trans
import Control.Monad.Trans.Except
import Control.Monad.Trans.State
newtype MyTransT m a = MyTransT (m a)
foo :: (MonadTrans t, Monad (t (Either e))) => MyTransT (t (Either e)) a -> a
foo = undefined
bar :: MyTransT (StateT Int (Either e)) a
bar = undefined
baz :: MyTransT (StateT Int (StateT Int (Either e))) a
baz = undefined
x = foo bar -- works
y = foo baz -- doesn't work
在本質上,我想創建它接受一個單子變壓器堆的功能,具有指定的堆疊的頂部和底部,而中間可以是任何東西。
抓我的頭一會兒,爲什麼foo baz
正在與Couldn't match type ‘StateT Int (Either e1)’ with ‘Either e0’
拒絕後,它終於發生,我認爲在這種情況下,我是假設t
爲StateT Int (StateT Int)
這不僅不是一個MonadTrans
,其無法正常打字/ kinded。
有什麼方法可以完成我正在嘗試做的事情,還是有時間嘗試不同的方法?
你能舉出一些具體的例子,說明你希望'foo'在實踐中工作嗎? – ErikR
想象一下你有一個'T'類型,它可以被認爲是'K'類型的'V'類型的容器。現在想象每個'V'也遵循這種模式。我想有'foo :: StateT V(t(E))a - > StateT T(ReaderT K(t(E或e)))a'。這將對'V'進行有狀態操作,並通過'T'將它們置於有'K'環境的有狀態操作。基本上是一個樹結構,我可以無限地向上和向下延伸,而無需更改現有的代碼。 – user2085282
具體例子在這裏會更有幫助。隨意將它放在你的問題中,它會更容易閱讀。 – ErikR