2014-09-05 22 views
6

Haskell, örneğini T1'da ancak çok benzer bir tür olan T2'da türetmeyebilir. T2 için kodu nasıl değiştirmeliyim, böylece MonadState s örneği otomatik olarak türetilebilir mi?Genelleştirilmiş Newtype Türetme

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

import Control.Monad.Reader 
import Control.Monad.State 

newtype T1 r s a = 
    T1 { runT1 :: ReaderT r (State s) a } 
    deriving (Monad, MonadReader r, MonadState s) 

newtype T2 r s a = 
    T2 { runT2 :: StateT r (State s) a } 
    deriving (Monad, MonadState r, MonadState s) 

cevap

7

Tür için MonadState iki örneğiniz olamaz. MonadState

anahtar bölümü | m -> s olan
class Monad m => MonadState s m | m -> s where 
    get :: m s 
    set :: s -> m() 
    state :: (s -> (a, s)) -> m a 

olarak tanımlanır olmasıdır. Bu, FunctionalDependencies uzantısını gerektirir ve m için, ilgili s'u otomatik olarak bildiğimizi belirtir. Bu, herhangi bir m için, geçerli olan s için yalnızca bir seçeneğinin seçilebileceği anlamına gelir. Bu nedenle,ve MonadState s m için r ~ s sürece çalışmaz. r ~ s ise, derleyici bunun için hangi temel monadın uygulanacağını nasıl biliyor? Bu durumda, get ve put işlevlerini oluşturup, getInner, setInner ve getOuter, setOuter gibi belirtmek için eklere sahip olan kodları anlamanız ve bu kodla çalışmanız çok daha kolay olacaktır.