この質問は明らかに、hereとhereで説明されている問題に関連しています。残念ながら、私の要求はそれらの質問とは少し異なり、与えられた答えは私には当てはまりません。私も実際に理解していませんなぜrunST
はこれらのケースではタイプチェックに失敗しますが、これは役に立たない。トランススタックでSTTモナドをアンラッピングしますか?
私の問題はこれです、私は1つのモナドスタック、またはむしろ単一モナドを使用するコードのいずれかのセクションがあります。
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
の内部モナドが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
私も試してみた:より強く、問題の原因だった場合には、その期待される戻り値の型からrunST
を分離するために
runToKErr r = either throwError return $ runExcept $ runST r
を、が、結果は同じです。
s1
のタイプはどこから来ていますか.GHCにはs
と同じタイプがあると説得するにはどうすればよいですか?