2011-05-07 14 views
11

से TypeRep मिल रहा इस प्रकार के हस्ताक्षर के साथ एक समारोह लिखना चाहते हैं:हास्केल - ठोस प्रकार उदाहरण

getTypeRep :: Typeable a => t a -> TypeRep 

जहां TypeRep एक टी के लिए नहीं एक के लिए प्रकार प्रतिनिधित्व हो जाएगा। यही है, संकलक को स्वचालित रूप से किसी भी कॉल साइट पर सही प्रकार का प्रतिनिधित्व वापस करना चाहिए [getTypeRep], जिसमें के लिए ठोस प्रकार होंगे।

कुछ संदर्भ जोड़ने के लिए, मैं एक "गतिशील प्रकार" डेटा प्रकार बनाना चाहता हूं, मोड़ के साथ कि यह शीर्ष-स्तर के प्रकार को याद रखेगा, लेकिन इसका पैरामीटर नहीं। उदाहरण के लिए, मैं गतिशील MyClass में MyClass एक चालू करना चाहते हैं, और इसके बाद के संस्करण समारोह गतिशील MyClass के उदाहरण है कि प्रकार पैरामीटर एक का प्रतिनिधित्व स्टोर बनाने के लिए इस्तेमाल किया जाएगा।

उत्तर

9

ठीक है, कैसे आंतरिक घटक चयन करने के लिए दायरे वाला प्रकार चर का उपयोग कर के बारे में:

मेरे लिए
{-# LANGUAGE ExplicitForAll #-} 
{-# LANGUAGE ScopedTypeVariables #-} 

import Data.Dynamic 
import Data.Typeable 

getTypeRep :: forall t a . Typeable a => t a -> TypeRep 
getTypeRep _ = typeOf (undefined :: a) 

काम करता है:

*Main> getTypeRep (Just()) 
() 
*Main> getTypeRep (Just 7) 
Integer 
*Main> getTypeRep ([True]) 
Bool 

दिलचस्प डिजाइन।

8

डॉन के समाधान के लिए एक स्पर्शिक नोट पर, ध्यान दें कि कोड शायद ही कभी ScopedTypeVariables की आवश्यकता है। यह सिर्फ समाधान क्लीनर बनाता है (लेकिन कम पोर्टेबल)। स्कोप प्रकार के बिना समाधान है:

{-# LANGUAGE ExplicitForAll #-} 
import Data.Typeable 

helper :: t a -> a 
helper _ = undefined 

getTypeRep :: forall t a. Typeable a => t a -> TypeRep 
getTypeRep = typeOf . helper