haskell - Unwrapping the STT monad in a transformer stack? -
this question apparently related problem discussed here , here. unfortunately, requirement different questions, , answers given don't apply me. don't understand why runst
fails type check in these cases, doesn't help.
my problem this, have 1 section of code uses 1 monad stack, or rather single monad:
import control.monad.except type kerr = except kinderror
another section of code needs integrate wraps within stt monad:
type runm s = stt s (except kinderror)
at interface between these sections, need wrap , unwrap outer layer. i've got following function work in kerr
-> runm
direction:
kerrtorun :: kerr -> runm s kerrtorun e = either throwerror return $ runexcept e
but reason can't converse type check:
runtokerr :: runm s -> kerr runtokerr r = runst r
i'm working on assumption runm
's inner monad has same structure kerr
, can return once i've unwrapped stt
layer, don't seem able far, runst
complains type arguments:
src/kindlang/runtime/eval.hs:18:21: couldn't match type ‘s’ ‘s1’ ‘s’ rigid type variable bound type signature runtokerr :: runm s -> kerr @ src/kindlang/runtime/eval.hs:17:14 ‘s1’ rigid type variable bound type expected context: stt s1 (exceptt kinderror data.functor.identity.identity) @ src/kindlang/runtime/eval.hs:18:15 expected type: stt s1 (exceptt kinderror data.functor.identity.identity) actual type: runm s
i've tried:
runtokerr r = either throwerror return $ runexcept $ runst r
in order more isolate runst
expected return type, in case cause of issue, results same.
where s1
type coming from, , how persuade ghc it's same type s
?
(the below talks st s a
applies same stt s m a
; i've avoided unnecessary complication of talking transformer version below)
the problem seeing runst
has type (forall s. st s a) -> a
isolate potential (stref
-changing) effects of computation outside, pure world. whole point of s
phantom type st
computations, stref
s, etc. tagged with, track "st
-domain" belong to; , type of runst
ensures nothing can pass between domains.
you can write runtokerr
enforcing same invariant:
{-# language rank2types #-} runtokerr :: (forall s. runm s a) -> kerr runtokerr = runst
(of course, might realize further down road restriction strong program hope write; @ point you'll need lose hope, sorry, mean you'll need redesign program.)
as error message, reason can't "convince type checker s1
, s
same type" because if pass st s a
given choice of s
, a
, not same giving allows choose own s
. ghc chose s1
(a skolemized variable) s
, tries unify st s a
st s1 a
Comments
Post a Comment