2010-07-30 15 views
7

Est-il possible d'utiliser des synonymes de type comme arguments du constructeur de type monad transformers? En particulier, s'il existe un synonyme de type unaire pour un transformateur monad appliqué, pourrait-il être utilisé comme type de monade sous-jacente dans un autre transformateur monad?Utilisation de synonymes de type dans les transformateurs monad

D'après ce que je vois synonymes de type ne sont pas acceptés en tant que constructeurs de type de première classe, voir exemple les messages et d'erreur ci-dessous:

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

Y at-il un moyen d'éviter l'élargissement du type synonyme A dans la définition de B a ?

Répondre

12

Les synonymes de type ne peuvent pas être appliqués partiellement. Dans ce cas précis, vous pouvez écrire

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

[ou mieux encore type B = ReaderT String A utiliser B dans un autre transformateur monade]

Il est général, cette transformation est impossible sans utiliser New Type/données, par exemple:

type A a = Reader a Int 

ne peut pas être écrit de façon équivalente en tant que type A = .... Dans un certain sens, cette fonctionnalité serait équivalente à lambda de niveau de type \a -> Reader a Int.