2010-07-30 6 views
7

Ist es möglich, Typ Synonyme als Argumente der Typkonstruktor Monade Transformer zu verwenden? Kann es, wenn es ein unäres Synonym für einen angewandten Monadentransformator gibt, als ein Typ der zugrundeliegenden Monade in einem anderen Monadentransformator verwendet werden?Verwendung von Typ Synonyme in Monade-Transformer

Von dem, was ich sehe, Typ Synonyme als First-Class-Typkonstruktoren nicht akzeptiert werden, siehe Beispiel und Fehlermeldungen unter:

-- 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 

Gibt es eine Möglichkeit, die Art Synonym A in der Definition von B a Erweiterung zu vermeiden ?

Antwort

12

Typ Synonyme können nicht teilweise angewendet werden. In diesem speziellen Fall können Sie

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

schreiben [oder noch besser type B = ReaderT String AB in einem anderen Monade Transformator verwenden]

Es ist allgemein, dass Transformation ist unmöglich ohne newtype/Daten zu verwenden, zum Beispiel:

type A a = Reader a Int 

kann nicht äquivalent als type A = ... geschrieben werden. In gewissem Sinne wäre dieses Merkmal äquivalent zum Lambda-Typ \a -> Reader a Int.