2013-05-09 10 views
5

यहाँ एक बहुत उपयोगी वर्ग है:सार्वभौमिक सामान्यीकृत कमी

class Foo f a where 
    foo :: f a 

यह चलो मुझे प्रकार के बहुत सारे के लिए डिफ़ॉल्ट मान सकते हैं। वास्तव में, मुझे यह जानने की भी आवश्यकता नहीं है कि a क्या है।

instance Foo Maybe a where 
    foo = Nothing 

अब मैं सब a के लिए एक Maybe a है, और मैं इसे बाद में विशेषज्ञ कर सकते हैं।

specialize :: (forall a. f a) -> f Int 
specialize x = x 

fooMaybe :: Maybe Int 
fooMaybe = specialize foo 

हमम .... कि fooMaybe निश्चित रूप से बहुत विशिष्ट लगता है। चलो देखते हैं कि मैं इसे सामान्यीकृत करने के लिए संदर्भ का उपयोग कर सकता हूं:

fooAll :: (Foo f a) => f Int 
fooAll = specialize foo 

ओह! अनुमान नहीं।

Foo.hs:18:21: 
    Could not deduce (Foo * f a1) arising from a use of `foo' 
    from the context (Foo * f a) 
     bound by the type signature for fooAll :: Foo * f a => f Int 
     at Foo.hs:17:11-28 

तो, मेरे सवाल का, मैं कैसे fooAll लिख सकते है, fooMaybe की सामान्यीकृत संस्करण? या, अधिक आम तौर पर, मैं टाइपस्लास बाधा को सार्वभौमिक रूप से सामान्य कैसे कर सकता हूं?

+1

आप अपडेट नहीं कर पाएंगे। खैर, आप 'fooAll' लिख सकते हैं यदि आप' example foo f जहां foo = undefined' बनाते हैं। लेकिन यह उपयोगी नहीं है। आप सार्वभौमिक रूप से बाध्यता को प्रमाणित नहीं कर सकते हैं, आप 'fooAll :: (forall a। Foo f a) => f Int' नहीं लिख सकते हैं। –

उत्तर

7

अभी वर्तमान हास्केल में कोई अच्छा तरीका नहीं है। constraints पैकेज एक प्रकार प्रदान करता है जो do what you need हो सकता है, हालांकि, मैंने हाल ही में यह पता लगाया कि इसे कैसे तोड़ना है। फिर भी शायद आपकी सबसे अच्छी शर्त, क्योंकि अगर कोई इसे सही तरीके से कैसे करना है, तो यह शायद

fooAll :: Forall (Foo f) => f Int 
fooAll = specialize foo_f where 
    foo_f :: forall a. f a 
    foo_f = foo \\ (inst `trans` (Sub Dict) ::() :- Foo f a) 
संबंधित मुद्दे