0

가 나는 동안, 지정된 스택의 상단과 하단으로, 모나드 변압기 스택을 받아들이는 기능을 만들려고하고있는 다음 코드임의 모나드 변압기 스택

본질적으로
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 bazCouldn't match type ‘StateT Int (Either e1)’ with ‘Either e0’으로 거부되는 이유에 관해서는 잠시 동안 내 머리를 긁적 후, 마침내 그 경우에, 나는 t가이 제대로 입력하지 만이 아닌 MonadTrans하지 않은 StateT Int (StateT Int) 것을 가정 것을 나에게 발생/kinded.

내가하려는 일을 수행 할 방법이 있습니까? 아니면 다른 접근 방식을 시도 할 시간입니까?

+0

'foo'가 실제로 어떻게 작동하는지 몇 가지 구체적인 예를 들려 줄 수 있습니까? – ErikR

+0

타입이'T' 인 것을 상상해보십시오.이 타입은'K' 타입의 키를 가진'V' 타입의 컨테이너로 생각할 수 있습니다. 이제 각각의 'V'도이 패턴을 따른다고 상상해보십시오. 나는'foo :: StateT V (t (어느 쪽인가)) a -> StateT T (ReaderT K (t (어느 쪽인가))) a'를 원합니다. 이렇게하면'V '에 대한 상태 저장 작업을 수행하고'K '환경이있는'T'에 대한 상태 저장 작업으로 들어갈 수 있습니다. 기본적으로 기존의 코드를 변경하지 않고도 무한히 위쪽과 아래쪽으로 확장 할 수있는 트리 구조입니다. – user2085282

+0

구체적인 예가 더 도움이 될 것입니다. 질문을 쉽게 읽을 수있는 곳으로 자유롭게 넣으십시오. – ErikR

답변

0

tEither e 모나드 이상의 변압기가 아니기 때문에 모나드 이상의 변압기이기 때문에 foo baz이 유형 검사를하지 않는 이유는 다음과 같습니다. 여기

은 구문 분석하는 방법이다 : m 양식 Either e하지입니다

baz :: MyTransT (StateT Int (StateT Int (Either e))) a 
        \________/ \_____________________/ 
         t   m     a 

하는 것으로.

새 변압기를 만들 수 있습니다. 이 같은 StateTIntStateTInt, 쓰기 바즈 :

baz :: MyTransT (StateTIntStateInt (Either e)) a 

후 수표를 입력합니다. 예를 들어 :

그러나
type StateTIntStateTInt = StateT (Int,Int) 

baz' :: MyTransT (StateTIntStateTInt (Either e)) a 
baz' = undefined 

test = foo baz' 

, 당신은 내가 의심 유형의 문제를 해결하더라도 당신은 기능 foo을 쓸 수 을 것입니다.

bar0 :: MyTransT (StateT Int (Either String)) Int 
bar0 = MyTransT $ lift $ Left "blather" 

무엇 int 값해야 foo bar0 반환 : bar이 특정 값을 무엇을 반환해야 고려?

+0

나는 이것을 깨닫고, 심지어 질문에서 그것을 지적한다. 요점은'foo'가 임의의 스택의 트랜스포머를 받아 들일 수 있어야한다는 것이었고, 따라서 모든 가능성을위한 newtype을 만드는 것은 거의 불가능 해 보입니다. 또한'foo'의 리턴 타입은 자리 표시 자입니다. 스 니펫은 문제를 보여주기위한 것이 었습니다. 실제로,'foo'는't (Either e)'와 관련된 값을 리턴합니다. – user2085282