2012-03-07 9 views
9

मुझे लगता है कि मैं जो चाहता हूं वह टेम्पलेट हास्केल के बिना असंभव है लेकिन मैं वैसे भी पूछूंगा।सभी प्रकार के पारिवारिक उदाहरणों पर टाइप बाधाएं

मैं Data.Set और Data.IntSet तरह प्रकार के लिए एक इंटरफेस है:

type family Elem s :: * 
class SetLike s where 
    insert :: Elem s -> s -> s 
    member :: Elem s -> s -> Bool 
    ... 

type instance Elem (Set a) = a 
instance Ord a => SetLike (Set a) where 
    ... 

और मैं एक प्रकार परिवार जो इष्टतम सेट कार्यान्वयन चुनता है:

type family EfficientSet elem :: * 
type instance EfficientSet Int = IntSet 
type instance EfficientSet String = Set String -- or another implementation 

कोई गारंटी नहीं है कि EfficientSet उदाहरणों एक रास्ता है हमेशा SetLike और Elem (EfficientSet a)a होगा?

इस गारंटी सभी समारोह हस्ताक्षर इस तरह होगा बिना:

type LocationSet = EfficientSet Location 
f :: (SetLike LocationSet, Elem LocationSet ~ Location) => ... 

हर बार SetLike LocationSet कुछ हद तक संतोषजनक है लिखने के लिए, लेकिन Elem LocationSet ~ Location, केवल कठिन कोड समझ में आता है मेरे लिए के रूप में।

उत्तर

7

GHC 7.4 की बाधा प्रकार का उपयोग करके आप की तरह

type EfficientSetLike a = (SetLike (EfficientSet a),Elem (EfficientSet a) ~ a) 

आप (उचित एक्सटेंशन के साथ) कर सकते हैं कुछ हो सकता था, GHC

के पुराने संस्करणों में इस तरह की कमी मिल
class (SetLike (EfficientSet a),Elem (EfficientSet a) ~ a) => EfficientSetLike a 
instance (SetLike (EfficientSet a),Elem (EfficientSet a) ~ a) => EfficientSetLike a 

लेकिन नए शैली type घोषणा बहुत अच्छी है।

मुझे बिल्कुल यकीन नहीं है कि आप क्या खोज रहे हैं, लेकिन ऐसा लगता है कि आप बाधा हस्ताक्षर लिखना/समझना आसान चाहते हैं, इस मामले में यह काम करेगा।

+0

सच? एक 'प्रकार' समानार्थी घोषणा न केवल एक प्रकार का समानार्थी परिभाषित कर सकती है, लेकिन एक प्रकार की बाधा समानार्थी? दिलचस्प। क्या यह अंतर्निहित पैरामीटर प्रकार की बाधाओं के साथ भी काम करता है? –

+0

@ जेफबर्जेस हाँ: http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/constraint-kind.html –

2

आप यह लिख सकते हैं:

class SetLike s where 
    type Elem s 
    insert :: Elem s -> s -> s 
    member :: Elem s -> s -> Bool 

class Elem (EfficientSet a) ~ a => HasEfficientSet a where 
    type EfficientSet a 
1

मैं डैनियल की तरह:

class (SetLike (EfficientSet a), Elem (EfficientSet a) ~ a) => 
     HasEfficientSet a where 
    type EfficientSet a 

आप SetLike वर्ग के साथ Elem प्रकार परिवार सहयोगी, तो आप शायद भी SetLike सुपर क्लास बाधा की जरूरत नहीं होगी वाग्नेर की पोस्ट, लेकिन आप केवल लिख नहीं सकते:

test :: (HasEfficientSet a) => EfficientSet a 
test = empty 

आप लिखने के लिए है:

test :: (HasEfficientSet a, SetLike (EfficientSet a)) => EfficientSet a 
test = empty 

लेकिन यह एक बाधा पर्याय के साथ दूर किया जा सकता:

class SetLike s where 
    type Elem s :: * 
    empty :: s 
    insert :: Elem s -> s -> s 
    member :: Elem s -> s -> Bool 

class (Elem (EfficientSet a) ~ a) => HasEfficientSet' a where 
    type EfficientSet a :: * 

type HasEfficientSet a = (HasEfficientSet' a, SetLike (EfficientSet a)) 


newtype UnitSet = UnitSet Bool 
    deriving (Show, Eq, Ord) 

instance SetLike UnitSet where 
    type Elem UnitSet =() 
    empty = UnitSet False 
    insert() _ = UnitSet True 
    member() u = UnitSet True == u 

instance HasEfficientSet'() where 
    type EfficientSet() = UnitSet 


test :: (HasEfficientSet a) => EfficientSet a 
test = empty 

test1 :: EfficientSet() 
test1 = empty 

test2 :: EfficientSet() 
test2 = test 

test3 :: UnitSet 
test3 = empty 

test4 :: UnitSet 
test4 = test 
संबंधित मुद्दे