2013-01-04 17 views
5

मैं एक आवेदक मज़ेदार पर काम कर रहा हूं जिसमें निष्पादन को "देखने" के लिए एक मोनॉयड शामिल है। हालांकि, कभी-कभी मुझे इस हिस्से की परवाह नहीं है, इसलिए मोनोइड की पसंद अप्रासंगिक है क्योंकि इसे कभी भी उपभोग नहीं किया जाएगा। मैं सरल बना दिया है कि मैं क्या में है:बाधाओं का प्रकार और 'सीमित' बाधाओं वाले परिवारों का प्रकार

{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE ConstraintKinds #-} 
{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE TypeFamilies #-} 

import GHC.Exts 

class Render a b where render :: a -> b 
instance Render a() where render = const() 

class Merge a where 
    type Renderer a b :: Constraint 
    merge :: Renderer a b => a -> b 

data Foo = Foo Bool 

instance Merge Foo where 
    type (Renderer Foo) m = (Render Bool m) 
    merge (Foo b) = render b 

Render एक भी b में विभिन्न a रों को बदलने के लिए प्रयोग किया जाता है। Merge मेरे वास्तविक मज़ेदार का एक बड़ा सरलीकरण है, लेकिन बिंदु यह है कि इसमें एक प्रकार का परिवार/बाधा शामिल है और इसका मेरा इरादा यह निर्दिष्ट करना है कि Render ers Merge आवश्यक है।

अब, मैं करने के लिए "रन" Merge चाहते हो सकता है, लेकिन त्यागने देखने के लिए, जो की तरह कुछ के लिए समान है:

runFoo :: Merge a => a -> Int 
runFoo x = case merge x of() -> 5 

लेकिन यह असफल हो जायेगी क्योंकि:

अनुमान नहीं किया जा सका (Renderer a())merge

का एक प्रयोग मैं क्योंकि च मेरी monoid रूप () चुना है से उत्पन्न होने वाली Orall a, हमारे पास Render a() का एक उदाहरण है। तो अगर कहने का कोई तरीका था कि Merge a का मतलब सिर्फ Render बाधाओं का संग्रह है तो यह ठीक काम करेगा। बेशक, Merge a उससे अधिक सामान्य है - यह मनमाने ढंग से बाधाओं को जोड़ सकता है, जो संकलन त्रुटि बताता है।

क्या runFoo के हस्ताक्षर को बदलने के बिना मैं क्या चाहता हूं?

+0

है 'Renderer' हमेशा वास्तव में शामिल एक' Render'? –

+0

@ टिनक्टरियस - नहीं, आम तौर पर 'Foo' – ocharles

+0

के फ़ील्ड में विशिष्ट प्रकारों की मात्रा पर निर्भर करता है क्या कोई कारण है कि 'मर्ज' में पैरामीटर के रूप में भी' b' नहीं है? –

उत्तर

6

अगर आप इन मामलों में से एक बहुत कुछ है पैमाने पर नहीं हो सकता है, लेकिन यह काम करता है:

class Renderer a() => Merge a where 
    ... 
+0

मैंने इसे नहीं माना था। मैं उस बाधा को 'मर्ज' के रूप में कम से कम '()' monoid 'के साथ प्रतिपादन का समर्थन करना चाहिए। हालांकि, यह 'UndecidableInstances'' होता है। – ocharles

+0

"अपरिहार्य इंस्टेंस एक खतरनाक ध्वज नहीं है। यह कभी भी टाइप-चेकर को ऐसे प्रोग्राम को स्वीकार करने का कारण नहीं देगा जो गलत हो। ध्वज का उपयोग करने का एकमात्र बुरा परिणाम टाइप चेकर का हमें बता रहा है कि यह तय नहीं कर सकता कि हमारा प्रोग्राम अच्छी तरह से टाइप किया गया है, संदर्भ-स्टैक-गहराई सीमा के अनुसार। " http://okmij.org/ftp/Haskell/TypeClass.html#undecidable-inst-defense –

+0

मुझे पता है कि, मैं इसे पहले से ही 3 अन्य स्थानों में उपयोग करता हूं;) लेकिन आदर्श रूप से मुझे उन समाधानों को ढूंढना पसंद है जिन्हें इसकी आवश्यकता नहीं है, भले ही पूरी तरह अकादमिक कारणों के लिए। मैं शायद इस जवाब को स्वीकार करूंगा, हालांकि जमीन थोड़ी देर के लिए खुली रहती है। यह वास्तव में एक इलाज काम कर रहा है! – ocharles

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