2011-09-01 12 views
7

में पूर्णांक द्वारा पैरामीटरेटिंग प्रकार मैं कुछ हास्केल प्रकार बनाने की कोशिश कर रहा हूं जो पैरामीटर द्वारा प्रकार के नहीं हैं बल्कि एक प्रकार के तत्वों, विशेष रूप से, पूर्णांक हैं। उदाहरण के लिए, आर^2 में एक (रैखिक-बीजगणित) वेक्टर और आर^3 में एक वेक्टर अलग टाइप की गई वस्तुएं हैं। विशेष रूप से, मैं हास्केल में एक के-डी पेड़ लिख रहा हूं और मैं अपने डेटा-स्ट्रक्चर को सकारात्मक पूर्णांक द्वारा पैरामीट्रिज करना चाहता हूं ताकि 3-डी पेड़ और 4-डी पेड़ के अलग-अलग प्रकार हों।हास्केल

मैंने अपने पेड़ को टपल्स द्वारा पैरामीट्रिज करने की कोशिश की है, लेकिन ऐसा लगता है कि यह कहीं भी नहीं जा रहा है (और ऐसा लगता है कि इसे कुछ हद तक असंभव रूप से देखा जा सकता है, विशेष रूप से ऐसा लगता है कि ट्रिपल या कुछ भी बड़ा नहीं है । इस तरह

data (TupleOfDoubles a) => KDTree a b = ... ---so in a 3DTree a is (Double,Double,Double) 

कि अच्छा होगा, या कुछ और होगा: भी functors मैं इस तरह कुछ करना चाहता हूँ (और मैं उदाहरण HomogeneousTuple एक => functor एक तरह कहने के लिए, किसी भी तरह से पता नहीं है) समान रूप से अच्छा

data KDTree Int a = ... -- The Int is k, so KDTree has kind Int -> * -> * 

क्या इनमें से कोई भी जानता है या नहीं प्रभाव व्यावहारिक या उचित हैं?

धन्यवाद -Joseph

+4

एक साइड-नोट, आप निर्भर प्रकारों पर कुछ साहित्य में रूचि रख सकते हैं, जो मूल्यों से लेकर प्रकारों के कार्यों का एक सामान्य प्रकार है: मैंने http://www.cse.chalmers.se/~peterd का आनंद लिया /papers/DependentTypesAtWork.pdf –

+0

धन्यवाद आमोस, ऐसा लगता है कि मैं –

उत्तर

5

वहाँ एक GHC विस्तार TypeNats कहा जाता है पर काम किया जा है, जो वास्तव में आप क्या चाहते हो जाएगा है। हालांकि इसके लिए मील का पत्थर वर्तमान में the ticket के अनुसार 7.4.1 होना है, इसलिए यह अभी भी प्रतीक्षा का थोड़ा सा होगा।

जब तक कि एक्सटेंशन उपलब्ध न हो, केवल एक चीज जो आप कर सकते हैं, प्रकारों का उपयोग करके आयाम को एन्कोड करना है। उदाहरण के लिए इन पंक्तियों के साथ कुछ काम कर सकते हैं:

{-# LANGUAGE ScopedTypeVariables #-} 
class MyTypeNat a where 
    toInteger :: a -> Integer 

data Zero 
data Succ a 

instance MyTypeNat Zero where 
    toInteger _ = 0 

instance MyTypeNat a => MyTypeNat (Succ a) where 
    toInteger _ = toInteger (undefined :: a) + 1 

data KDTree a b = -- ... 

dimension :: forall a b. MyTypeNat a => KDTree a b -> Integer 
dimension = toInteger (undefined :: a) 

इस तरह एक दृष्टिकोण का नकारात्मक पहलू बेशक आप KDTree (Succ (Succ (Succ Zero))) Foo बजाय KDTree 3 Foo की तरह कुछ लिखने के लिए है कि है।

+1

का उपयोग कर सकता हूं, लेकिन फिर एक प्रकार तीन = Succ (Succ (Succ Zero)) मदद करेगा। – Ingo

+0

निफ्टी, धन्यवाद (यह थोड़ा मूर्ख है, लेकिन मैं वास्तव में खुदाई करता हूं) –

+0

यदि आप केवल छोटी संख्याओं का उपयोग करने जा रहे हैं, तो आप उन्हें सीधे एन्कोड भी कर सकते हैं: डेटा एक/डेटा दो/डेटा तीन/डेटा चार - यह है पढ़ने के लिए आसान है। – firefrorefiddle

3

sepp2k का उत्तर ऐसा करने के लिए मूल दृष्टिकोण दिखाता है। वास्तव में, बहुत से काम पहले से ही किया जा चुका है।

प्रकार स्तरीय संख्या संकुल

प्राकृतिक संख्याओं का सामान का उपयोग कर प्रकार स्तरीय एनकोडिंग (उदाहरण)

दुर्भाग्य से कुछ इस तरह:

data KDTree Int a = ... 

वास्तव में संभव नहीं है। अंतिम प्रकार (KDTree द्वारा निर्मित) Int के मान पर निर्भर करता है, जिसके लिए आश्रित प्रकार नामक सुविधा की आवश्यकता होती है।आगाडा और एपिग्राम जैसी भाषाएं इसका समर्थन करती हैं, लेकिन हास्केल नहीं।

+0

इसके लिए धन्यवाद। ऐसा करने के लिए सीखने के लिए वीईसी मेरे लिए सबसे आसान संभव उदाहरण की तरह लगता है। –

+0

हां, वीईसी शायद सबसे सरल, फिर आयामी है। llvm और ForSyDe अधिक जटिल हैं, हालांकि मुझे लगता है कि वे मूल रूप से केवल वही के रूप में एक ही चीज़ को लागू करते हैं। –