2013-04-04 8 views
6

मैं हैकेल में एक ज्यामिति पुस्तकालय को एक साथ रख रहा हूं। मैं इसे जारी करने का इरादा नहीं रख रहा हूं, यह सिर्फ एक परियोजना है जिसका उपयोग मैं भाषा के बारे में अपने ज्ञान को बेहतर बनाने के लिए कर रहा हूं।टाइपक्लास और जीएडीटी

मैं निम्नलिखित परिभाषा

data Local a where 
    MkLocal :: (Vectorise a) => ReferenceFrame -> a -> Local a 

एक संदर्भ फ्रेम एक वेक्टर फ्रेम की उत्पत्ति और एक कोण फ्रेम के रोटेशन का प्रतिनिधित्व करने, दोनों परिभाषित wrt "पूर्ण की ओर इशारा करते है के साथ एक Local डेटाप्रकार है, "संदर्भ का फ्रेम (हे, यह असली दुनिया नहीं है!)। Vectorise ज्यामिति वह है जिसमें Vector की सूची में एक परिवर्तनीय परिवर्तन है।

यह मेरे लिए हुआ स्थानीय Functor का एक उदाहरण के रूप में निम्नानुसार हो सकता है कि:

instance Functor Local where 
    fmap f geom = localise (frame geom) (f $ local geom) 

लेकिन संकलक शिकायत परिभाषा में स्थानीयकरण के उपयोग के लिए Vectorisable का कोई उदाहरण नहीं है। क्या असंख्य जीएचसी एक्सटेंशन में से किसी एक का उपयोग करके इस सीमा के आसपास कोई रास्ता है?

संपादित करें: के रूप में टिप्पणी में अनुरोध किया है, यहाँ हैं प्रकार के कुछ

local :: Local a -> a 
frame :: Local a -> ReferenceFrame 
localise :: (Vectorise a) => ReferenceFrame -> a -> Local a 

इस्तेमाल किया त्रुटि,

No instance for (Vectorise b) 
    arising from a use of `localise' 
In the expression: 
    localise (frame geom) (f $ local geom) 
In an equation for `fmap': 
    fmap f lgeom = localise (frame geom) (f $ local geom)) 
In the instance declaration for `Functor Local' 

कौन समझ में आता है, क्योंकि fmap के लिए प्रकार (a -> b) -> f a -> f b है। यह अनुमान लगा सकता है कि aVectorise का एक उदाहरण होना चाहिए, लेकिन मैं सोच रहा था कि यह b का अनुमान लगा सकता था, जब तक कि मैं निर्दिष्ट नहीं कर सकता था (किसी भी तरह) मैं संकलक को बता सकता हूं कि f में किसी अन्य टाइपक्लास को परिभाषित किए बिना प्रतिबंधित रिटर्न प्रकार होना चाहिए पहले से ही एक है कि लगभग बिल पहले से ही फिट करता है (या वैकल्पिक रूप से, अगर कोई मददगार तरीके से समझा सकता है कि इस तरह से कक्षाओं को प्रतिबंधित करने से किसी प्रकार का प्रकार कैसे टूट जाएगा)।

ps। मैं भी करने के लिए लिखने में कोई त्रुटि है, जहां मैं local और framefmap

+1

कृपया हमें 'लोकलाइज', 'लोकल' और 'फ्रेम' के प्रकार और आपको प्राप्त होने वाले त्रुटि संदेश दिखाएं। मेरा अनुमान है कि आप 'स्थानीय' के लिए 'आवृत्ति वेक्टरिस' खो रहे हैं। –

+0

हो गया। मैंने इंस्टेंस घोषणा जोड़ने की कोशिश की लेकिन इससे मदद नहीं मिली। यह 'f' का रिटर्न प्रकार है जिसे मुझे 'वेक्टरिस' के रूप में घोषित करने की आवश्यकता है, जहां तक ​​मैं देख सकता हूं, 'स्थानीय ए' नहीं। – ovangle

उत्तर

13
समस्या

की परिभाषा में उलट उलट था कि localise प्रकार Vectorise a => a के लिए अपनी दूसरी तर्क की आवश्यकता है तय है, लेकिन जब आप f लागू (a -> b टाइप है) local का परिणाम (Vectorise a => a टाइप करें), इस बात की कोई गारंटी नहीं है कि परिणामस्वरूप मान में टाइप होगा जो Vectorise का उदाहरण है। आप वास्तव में क्या चाहते हैं Functor का एक एनालॉग है जो केवल Vectorise बाधा वाले प्रकारों पर काम करता है।

हाल ही में, इस प्रकार के वर्गों को परिभाषित करना संभव नहीं था। यह एक प्रसिद्ध समस्या है और Data.Set का कारण Functor या Monad उदाहरण नहीं है। हालांकि, हाल के ConstraintKinds GHC विस्तार इस तरह के "प्रतिबंधित functors" के साथ अंत में संभव हो गया:

{-# LANGUAGE GADTs, ConstraintKinds, TypeFamilies #-} 
module Test 
     where 

import GHC.Exts (Constraint) 

data ReferenceFrame = ReferenceFrame 

class Vectorise a where 
    ignored :: a 

data Local a where 
    MkLocal :: ReferenceFrame -> a -> Local a 

local :: Vectorise a => Local a -> a 
local = undefined 

frame :: Local a -> ReferenceFrame 
frame = undefined 

localise :: (Vectorise a) => ReferenceFrame -> a -> Local a 
localise = undefined 

class RFunctor f where 
    type SubCats f a :: Constraint 
    type SubCats f a =() 
    rfmap :: (SubCats f a, SubCats f b) => (a -> b) -> f a -> f b 

instance RFunctor Local where 
    type SubCats Local a = Vectorise a 
    rfmap f geom = localise (frame geom) (f $ local geom) 

आप ConstraintKinds अधिक के बारे में here और here पढ़ सकते हैं।

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