कम्यूटेशन लागू करने के लिए हास्केल प्रकार की कक्षाओं का उपयोग करना


11

मैं ज्यामितीय वस्तुओं के लिए एक प्रकार के वर्ग को परिभाषित करना चाहता हूं जिन्हें एक साथ प्रतिच्छेद किया जा सकता है:

class Intersect a b c | a b -> c where
  intersect :: a -> b -> c
-- Language extensions: -XMultiParamTypeClasses, -XFunctionalDependencies

विचार एक सामान्य-उद्देश्य वाले चौराहे के कार्य हैं जो विभिन्न प्रकारों की वस्तुओं को संभाल सकते हैं। एक ऐसे उदाहरणों की कल्पना कर सकता है

instance Intersect Line Plane (Maybe Point) where
  ...
instance Intersect Plane Plane (Maybe Line) where
  ...

लेकिन मैं यह भी घोषित करना चाहता हूं कि चौराहा सराहनीय है:

instance (Intersect a b c) => Intersect b a c where
  intersect x y = intersect y x
-- Language extensions: -XUndecidableInstances

समस्या यह है कि जब भी मैं intersect x yफॉर्म के एक उदाहरण को परिभाषित किए बिना पहली बार मूल्यांकन करता हूं Intersect a b c, aतो इसका प्रकार कहां है xऔर bकिस प्रकार का है y, प्रोग्राम अनंत लूप में जाता है , संभवतः कम्यूटेटिविटी के बारे में पुनरावर्ती उदाहरण घोषणा के कारण होता है। आदर्श रूप से मैं चाहता हूं कि कुछ ऐसा intersect Egg Baconहो जो टाइप-चेक करने में विफल हो क्योंकि इस तरह की कोई भी घटना परिभाषित नहीं थी, न कि मुझे अनंत लूप में फंसाने की। मैं इसे कैसे लागू कर सकता हूं?


कुछ ऐसा लगता है जो आप टाइप परिवारों का उपयोग करने की कोशिश कर सकते हैं। आपको स्टैक ओवरफ्लो पर बेहतर प्रतिक्रिया मिल सकती है।
बेंजामिन होडसन

जवाबों:


2

सबसे पहले, आप कम्यूटेटिव पैकेज का उपयोग कर सकते हैं , जिस स्थिति में आप intersectनिम्न प्रकार के हस्ताक्षर को संशोधित करेंगे , लेकिन अन्यथा आपका कोड "बस काम" होगा:

instersect :: Commutative a b -> c

हालांकि, आप अपने टाइपकास्ट के सभी उदाहरणों पर संपत्ति परीक्षण चलाने के लिए क्विकचेक का उपयोग hspec के साथ भी कर सकते हैं ताकि यह सुनिश्चित हो सके कि यह वास्तव में कम्यूट करता है। यह ओवरहेड को कम कर सकता है - आपको एक बेंचमार्क करना होगा क्योंकि मैं अपने सिर के ऊपर से नहीं जानता। उदाहरण के लिए:

import Test.Hspec

main :: IO ()
main = hspec $ do
    describe "intersect" $ do
        parallel $ it "should commute" $ do
            property $ \x y -> intersect x y == intersect (y :: Point) (x :: Line)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.