2014-11-06 11 views
6

एक प्रकार वर्ग कि प्रकार स्तरीय प्राकृतिक की जेड स्वीकार करता है, (SZ) बनाने के लिए, (एस (SZ)) ... आदि, तो आप बस उदाहरणों रिकर्सिवली जैसे घोषणा कर सकते हैं:टाइप स्तर पूर्वानुमान आधारित उदाहरण टाइप करें?

data Z 
data S a 

class Type a 

instance Type Z 
instance Type (S a) 

यह है प्रकार स्तर के आधार पर एक प्रकार वर्ग उदाहरण बनाने के लिए संभव है? उदाहरण के लिए, मैं कहना है सक्षम होना चाहते हैं:

{-# LANGUAGE MultiParamTypeClasses #-} 
class Type a b 
instance Type x y when (x :+: y == 8) 

कहाँ :+: प्रकार स्तर है, और ==, Data.Type.Equality से टाइप स्तरीय समानता है ताकि उदाहरणों केवल Nats कि 8 को जोड़ने के जोड़े के लिए बनाई गई हैं ।

अंकन हास्केल में उपलब्ध इस के समान है? यदि नहीं, तो ऐसा कुछ कैसे पूरा किया जाएगा?

संपादित करें: इस पोस्ट by the Haskell wiki article on smart constructors, जहां एक प्रकार वर्ग InBounds स्थिर की पुष्टि है कि प्रेत प्रकार तर्क एक स्मार्ट निर्माता को पारित कर दिया Nat रों के कुछ सीमा में था घोषित किया गया था प्रेरित था, स्मार्ट निर्माता था:

resistor :: InBounds size => size -> Resistor size 
resistor _ = Resistor 

construct :: (Type a b) => a -> b -> MyType a b 
construct _ _ = MyType 

>>> Expected a type, but a has kind Nat… 

हास्केल विकी है उदाहरण के काम करता है, क्योंकि यह 'नहीं करता है:

(leftaroundabout का जवाब उपयोग करने के बाद) मेरे उदाहरण में इसी तरह कुछ करने के लिए कोशिश कर रहा है मुझे एक त्रुटि देता है डेटाकिंड्स का उपयोग नहीं करते हैं, क्या एक प्रकार के प्रकार Nat को मूल्य-स्तर फ़ंक्शन में पास करना संभव है?

उत्तर

8

आपको समानता भविष्यवाणी का उपयोग करने की आवश्यकता नहीं है लेकिन समानता बाधा (जिसे भाषा में बेक किया गया है, -XGADTs के साथ सक्षम)।

{-# LANGUAGE KindSignatures, DataKinds, MultiParamTypeClasses, FlexibleInstances, GADTs #-} 

import GHC.TypeLits 

class Type (a :: Nat) (b :: Nat) 

instance (a + b) ~ 8 => Type a b 

मन है कि इस जरूरी यह लग सकता है के रूप में रूप में उपयोगी नहीं है - समानता बाधा किसी तरह सभी संयोजनों कि 8 को जोड़ने की गणना में नहीं है, बल्कि यह सब Nat -pairs उदाहरण हो सकते हैं , केवल एक सबूत कि वे 8. यह सबूत आप उपयोग कर सकते हैं को जोड़ने की मांग है, लेकिन मुझे शक है हास्केल अभी भी सिर्फ तरह-की -dependently टाइप किया प्रकृति यह काम बहुत अच्छी तरह से करता है।

+0

का जवाब देने के लिए धन्यवाद, लेकिन यह वास्तव में मुझे क्या करना है कोशिश कर रहा था के लिए बाहर काम नहीं किया, इसलिए मैं अपने प्रश्न को नवीनीकृत किया है और अधिक संदर्भ शामिल करने के लिए। –

+0

विकी पर यह उदाहरण प्रेत प्रकारों का उपयोग बेकार तरीके से करता है: आपको 'प्रतिरोधी' के लिए किसी भी तर्क की आवश्यकता नहीं है, बस इसे 'प्रतिरोधी :: इनबाउंड आकार => प्रतिरोधी आकार', 'प्रतिरोधी = प्रतिरोधी' बनाएं। यदि आपको किसी तर्क में डेटा-प्रकार वाले मान को लपेटने की आवश्यकता है, तो ['टैग की गईं]] (http://hackage.haskell.org/package/tagged) का उपयोग करें (जो मैं एक बड़ा प्रशंसक नहीं हूं, लेकिन कभी-कभी यह बस सही)। – leftaroundabout

+0

मेरा कोड बदलकर 'निर्माण :: (एक बी टाइप करें) => MyType a b' ,' निर्माण = MyType' अभी भी वही त्रुटि देता है। –

1

आप एक प्रकार स्तर समारोह

type family NatEq (a :: Nat) (b :: Nat) :: Bool 
type instance NatEq 0 0 = True 
... 

लिख सकता है और फिर

instance Type' (NatEq (a + b) 8) a b => Type a b 
class Type' (x :: Bool) (a :: Nat) (b :: Nat) where ... 
instance Type' True a b where ... 
-- If you wanted a different behaviour otherwise: 
-- instance Type' False a b where ... 

आप निश्चित रूप से, एक्सटेंशन का एक समूह को सक्षम करने की आवश्यकता होगी।

यह ठीक काम करता है अगर a और b, स्थिरांक हैं ताकि a+b8 (या किसी अन्य निरंतर) को कम किया जा सकता है। यदि वे स्थिरांक नहीं हैं, तो जीएचसी को आपके लिए समीकरण साबित करने की अपेक्षा न करें। यही कारण है कि (Nat के बजाय Int का प्रयोग करके), उम्मीद नहीं है Type x (8-x) हल किया जा रहा है।

संबंधित मुद्दे