2012-08-30 22 views
10

क्या एक दूसरे के संदर्भ में परिभाषित डिफ़ॉल्ट प्रकार के उदाहरण हैं? मैं इस काम के तरह कुछ पाने के लिए कोशिश कर रहा हूँ:डिफ़ॉल्ट प्रकार के उदाहरण एक दूसरे को संदर्भित करते हैं

{-# LANGUAGE DataKinds, KindSignatures #-} 
{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE UndecidableInstances #-} 
data Tag = A | B | C 

class Foo (a :: *) where 
    type Bar a (b :: Tag) 

    type Bar a A =() 
    type Bar a B = Bar a A 
    type Bar a C = Bar a A 

instance Foo Int where 
    type Bar Int A = Bool 

test :: Bar Int B 
test = True 

लेकिन यह काम नहीं करता:

Couldn't match type `Bar Int 'B' with `Bool' 
In the expression: True 
In an equation for `test': test = True 

ध्यान दें कि यह काम नहीं करता है या तो:

test :: Bar Int B 
test =() 

उत्तर

3

हाँ, डिफ़ॉल्ट प्रकार के उदाहरणों को एक-दूसरे के संदर्भ में परिभाषित किया जा सकता है (जैसा कि आप अपने उदाहरण से देख सकते हैं):

instance Foo Int where 
-- So the default recursive definition will be used instead 
-- type Bar Int A = Bool 

test :: Bar Int B 
test =() 

लेकिन जब आप Int के लिए अपने उदाहरण परिभाषा जुड़े को फिर से परिभाषित प्रकार पर्याय आप पूरे डिफ़ॉल्ट Bar की 3-लाइन defintion की जगह (और सिर्फ type Bar a A =() नहीं) एक पंक्ति type Bar Int A = Bool जिसका अर्थ है Bar Int B और Bar Int C परिभाषित नहीं रह रहे हैं के साथ।

तो मुझे लगता है कि तरीकों पुनरावर्ती चूक आपकी इच्छानुसार उपयोग करने के लिए में से एक के बजाय विशिष्ट समानार्थी शब्द को फिर से परिभाषित करने के लिए (हालांकि यह नहीं बल्कि अत्यधिक शब्द है):

class Foo (a :: *) where 
    type Bar a (b :: Tag) 
    type Bar a A = BarA a 
    type Bar a B = BarB a 

    type BarA a 
    type BarA a =() 

    type BarB a 
    type BarB a = Bar a A 

-- This now works 
instance Foo Int where 
    type BarA Int = Bool 

test :: Bar Int B 
test = True 

कौन सा चूक करना प्रारंभ कर सकते हैं:

-- As well as this one 
instance Foo Int where 
-- type BarA Int = Bool 

test :: Bar Int B 
test =() 
संबंधित मुद्दे