2010-07-30 11 views
7

È possibile utilizzare i sinonimi di tipo come argomenti del costruttore di tipi di trasformatori di monad? In particolare, se esiste un sinonimo di tipo unario per un trasformatore monade applicato, potrebbe essere usato come un tipo di monade sottostante in un altro trasformatore monad?Uso di sinonimi di tipo nei trasformatori monad

Da quello che vedo Sinonimi di tipo non sono accettate come tipo di prima classe costruttori, vedi esempio e di errore di seguito:

-- Using type synonym of a monad transformer in another monad transformer. 

import Control.Monad.Reader 

-- inner transformer 
type A a = ReaderT Int IO a 

-- type B a = ReaderT String A a 
{- Error: 
readert2.hs:8:0: 
    Type synonym `A' should have 1 argument, but has been given 0 
    In the type synonym declaration for `B' 
-} 

-- type B a = ReaderT String (A a) a 
{- Error: 
readert2.hs:15:27: 
    Kind mis-match 
    The second argument of `ReaderT' should have kind `* -> *', 
    but `A a' has kind `*' 
    In the type `ReaderT String (A a) a' 
    In the type synonym declaration for `B' 
-} 

type B a = ReaderT String (ReaderT Int IO) a 
{- OK -} 

main = do 
    r <- flip runReaderT 39 $ do 
      n <- ask :: A Int 
      s <- flip runReaderT "foo" $ (ask :: B String) 
      return $ n + length s 
    print r 

C'è un modo per evitare di ampliare il tipo sinonimo A nella definizione di B a ?

risposta

12

I sinonimi di tipo non possono essere applicati parzialmente. In questo caso specifico, è possibile scrivere

type A = ReaderT Int IO 
type B a = ReaderT String A a 

[o meglio type B = ReaderT String A usare B in un altro trasformatore monade]

È generale, che la trasformazione è impossibile senza utilizzare newtype/dati, ad esempio:

non può essere scritto in modo equivalente come type A = .... In un certo senso, questa funzione sarebbe equivalente a lambda \a -> Reader a Int.

Problemi correlati