2010-07-30 13 views
7

Monad transformatörlerinin tip kurucusunun argümanları olarak tip eşanlamlıları kullanmak mümkün müdür? Özellikle, uygulanan bir monad transformatörü için tek tip bir eşanlamlı varsa, başka bir monad transformatöründe altta yatan monadın bir türü olarak kullanılabilir mi? B a tanımında tipi eşanlamlı A genişleyen önlemek için bir yol var mıMonad transformatörlerindeki tip eşanlamlıların kullanımı

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

: Aşağıda örnek ve hata mesajlarına bakın, tip eş birinci sınıf tipi yapıcıları olarak kabul edilmemektedir bkz kadarıyla

?

cevap

12

Eş anlamlı kelimeler kısmen uygulanamaz. Bu özel durumda, yazabilir

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

[veya başka bir monad transformatör içinde B kullanmak type B = ReaderT String A daha iyi]

O transformasyon örneğin newtype/veri kullanmadan imkansız, general:

type A = ... eşdeğeri olarak yazılmaz. Bir anlamda, bu özellik tip seviye lambda \a -> Reader a Int'a eşdeğer olacaktır.