SbT
için tanımlamanın sizin istediğinizi sanmıyorum. Bu functor kompozisyonu'u tanımlar ve m
parametresinin Functor
veya Applicative
olduğunu varsayarsak, bu özellikler korunmalıdır. Fakat böyle bir kompozisyon, genelde, diğer iki kişiden yeni bir monad oluşturmaz. Bu konuda daha fazla bilgi için this question'a bakın.
nasıl yapılır, istediğiniz monad trafosunu oluşturursunuz, o zaman? Monadlar doğrudan oluşturmazken, monofil transformatörleri oluşturulabilir. Yani mevcut olanlardan yeni bir transformatör oluşturmak için, aslında sadece bu kompozisyona bir isim vermek istersiniz. Bu, sahip olduğunuz newtype
'dan farklıdır çünkü m
'u doğrudan trafo yığına iletmek yerine uygularsınız. Mono transformatörlerini tanımlamak için akılda tutulması gereken bir şey, belirli bir şekilde "geriye doğru" çalışmalarıdır - bir monoya kompozit bir trafo uygularken, "en içteki" transformatör ilk çatlağı alır ve ürettiği dönüştürülmüş monad, bir sonraki transformatörün & c ile çalıştığı şeydir. Bunun, bir bağımsız değişkene bir işlev uygularken aldığınız sıradan farklı olmadığını unutmayın. (f . g . h) x
, f
bileşimde "ilk" işlev olsa bile, ilk olarak h
argümanını verir.
Tamam, senin kompozit trafo uygulanacağına monad alıp uhm .... ayy, SB
bir monad uygulanan zaten olduğu ortaya çıktı olduğu en içteki transformatör, onu geçmek gerekiyor. Hiç şaşkınlık bu işe yaramadı. İlk önce bunu kaldırmamız gerekecek. Nerede? State
--we , numaralı telefonu kaldırabilir, ancak bunu yapmak istemiyoruz, çünkü sizin istediğiniz şeyin bir parçasıdır. Hmm, ama bekle - State
tekrar nasıl tanımlanır? Oh evet: işte başlıyoruz. Aha, işte başlıyoruz. Oradan Identity
çıkalım.
type SB' i m a = ReaderT (AlgRO i) (StateT (AlgState i) m) a
type SB i a = SB' i Identity a
Ama şimdi SB'
bir monad transformatör gibi şüpheyle bakar:
type SB i a = ReaderT (AlgRO i) (StateT (AlgState i) Identity) a
Sonra tembel serseri tekme: eşdeğer formda için
type SB i a = ReaderT (AlgRO i) (State (AlgState i)) a
: Biz mevcut tanımından gitmek tanımı ve iyi bir sebeple, çünkü öyle. Bu yüzden newtype
sarmalayıcı yeniden ve orada birkaç örneğini atmak: notu ait almaya
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
bir kaç şey: Burada runSbT
işlevi yerine her biri için bir bestelediği "run" fonksiyonu alan erişimci değil, bildiğimiz yığındaki transformatör. Benzer şekilde, lift
işlevinin, iki iç transformatör için bir kez kaldırması ve ardından son newtype
sarıcısını eklemesi gerekir. Bunların her ikisi de, aslında bir kompozit olduğu gerçeğini saklayarak, tek bir monad transformatör olarak çalışır.
İsterseniz, oluşturulmuş transformatörlerin örneklerini kaldırarak, MonadReader
ve MonadState
için örneklerin yazılması da basit olmalıdır.
bunu edeceğimizi. Teşekkürler! – dsign