2010-07-30 35 views
7

是否有可能使用類型同義詞作爲monad變換器類型構造函數的參數?特別是,如果應用單體變壓器有單一類型同義詞,是否可以將它用作另一單體變壓器中基礎單體的類型?在monad變換器中使用類型同義詞

從我所看到的類型同義詞不接受一流的類型構造,見例如和錯誤以下信息:

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

有沒有一種方法,以避免擴大類型同義詞AB a定義?

回答

12

類型同義詞不能部分應用。在這種特殊情況下,你可以寫

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

[甚至更好type B = ReaderT String A在另一個單子轉換使用B]

這是一般情況下,這種轉變是不可能的,而無需使用NEWTYPE /數據,例如:

type A a = Reader a Int 

不能等同寫成type A = ...。在某種意義上,這個特性將相當於類型級別的lambda \a -> Reader a Int

相關問題