2010-07-30 14 views
7

में समानार्थी शब्द का उपयोग करना क्या समानार्थी शब्द का उपयोग मोनैड ट्रांसफार्मर के प्रकार कन्स्ट्रक्टर के तर्क के रूप में करना संभव है? विशेष रूप से, यदि एक लागू मोनैड ट्रांसफार्मर के लिए एक यूनरी प्रकार समानार्थी है, तो क्या इसे किसी अन्य मोनैड ट्रांसफॉर्मर में अंतर्निहित मोनैड के प्रकार के रूप में उपयोग किया जा सकता है?मोनैड ट्रांसफार्मर

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

वहाँ एक रास्ता B a की परिभाषा में प्रकार पर्याय 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 = ... के रूप में नहीं लिखा जा सकता है। कुछ अर्थ में, यह सुविधा टाइप-लेवल लैम्ब्डा \a -> Reader a Int के बराबर होगी।

संबंधित मुद्दे