나는 SbT
에 대한 정의가 원하는 것이라고 생각하지 않습니다. 즉, 펑터 구성을으로 정의하고 m
매개 변수가 Functor
또는 Applicative
이라고 가정하면이 속성을 유지해야합니다. 그러나 그러한 구성은 일반적으로 두 개의 다른 모나드 중 하나에서 새로운 모나드를 생성하지 않습니다. 해당 주제에 대한 자세한 내용은 this question을 참조하십시오.
그래서 을으로 만들면 원하는 모나드 변환기를 만들 수 있습니까? 모나드는 직접 작성하지 않지만 모나드 변압기을 구성 할 수 있습니다. 따라서 기존 트랜스포머를 이용해 새로운 트랜스포머를 제작하려면 본질적으로 컴포지션에 이름을 지정하기 만하면됩니다. 이것은 newtype
과 다릅니다. 을 트랜스포머 스택에 전달하는 대신 직접 적용하기 때문입니다.
모나드 변압기를 정의하는 데있어 유의해야 할 점 중 하나는 모나드 변압기를 반드시 특정 방식으로 "거꾸로"작동한다는 것입니다. 모나드에 복합 변압기를 적용하면 "가장 안쪽에있는"변압기가 첫 번째 균열을 얻습니다. 생성 된 변환 된 모나드는 다음 변환기가 작동 할 것입니다. & c. 이것은 구성된 함수를 인수에 적용 할 때 얻는 순서와 다르지 않습니다. (f . g . h) x
은 h
의 인수를 먼저 제공합니다. f
이 컴포지션의 "첫 번째"기능 인 경우에도 마찬가지입니다.
좋아, 그래서 귀하의 복합 변압기는에 적용된 모나드를 가지고 음 .... 죄송합니다, SB
는 모나드에 적용 이미 것으로 밝혀이며, 가장 안쪽 변압기에 전달해야합니다. 이것이 작동하지 않는 것은 놀라운 일이 아닙니다. 먼저 그것을 제거해야합니다. 어디 있니? 아니 State
- 우리는 수 있지만 우리가하고 싶지 않아, 왜냐하면 당신이 원하는 부분입니다. 음,하지만 기다려 - State
은 무엇으로 정의 되었습니까? 오 그래 :
type State s = StateT s Identity
아하, 우리가 간다. 거기에 Identity
을 가져 가자.
type SB' i m a = ReaderT (AlgRO i) (StateT (AlgState i) m) a
type SB i a = SB' i Identity a
하지만 지금 SB'
는 모나드 변압기처럼 의심 같습니다
type SB i a = ReaderT (AlgRO i) (StateT (AlgState i) Identity) a
그런 다음 우리가 게으른 엉덩이를 걷어차 : 동등한 형성
type SB i a = ReaderT (AlgRO i) (State (AlgState i)) a
: 우리는 현재의 정의에서 이동 정의와 좋은 이유가있다. 그래서 우리는 newtype
래퍼를 재 작성하고 거기에 몇 가지 인스턴스를 던져 : 메모를 취할
newtype SbT i m a = SbT { getSB :: ReaderT (AlgRO i) (StateT (AlgState i) m) a }
instance (Functor m) => Functor (SbT i m) where
fmap f (SbT sb) = SbT (fmap f sb)
instance (Monad m) => Monad (SbT i m) where
return x = SbT (return x)
SbT m >>= k = SbT (m >>= (getSB . k))
instance MonadTrans (SbT i) where
lift = SbT . lift . lift
runSbT :: SbT i m a -> AlgRO i -> AlgState i -> m (a, AlgState t)
runSbT (SbT m) e s = runStateT (runReaderT m e) s
몇 가지 : 여기 runSbT
기능은 오히려 각각에 대해 구성된 "실행"기능 필드 접근이 아니라 우리가 알고있는 스택의 변압기. 마찬가지로 lift
함수는 두 개의 내부 변압기에 대해 한 번 들어 올린 다음 최종 newtype
래퍼를 추가해야합니다. 이 두 가지 모두 단일 모나드 변압기로 작동하며 실제로는 합성물이라는 사실을 숨 깁니다.
원하는 경우, 구성된 변환기에 대한 인스턴스를 해제하여 MonadReader
및 MonadState
에 대한 인스턴스를 작성하는 것이 간단해야합니다.
이렇게하면됩니다. 감사! – dsign