2016-01-10 8 views
8

reflection पैकेज एक वर्गक्या प्रतिबिंब जोखिम का असर पड़ता है?

class Reifies s a | s -> a where 
    reflect :: proxy s -> a 

और एक समारोह

reify :: a -> (forall s . Reifies s a => Proxy s -> r) -> r 

को देखते हुए प्रदान करता है केवल इन, एक सकता है गड़बड़ चीजों को नहीं बल्कि बुरी तरह से दे रही है, उदाहरण के लिए, उदाहरण के

instance Reifies s Int where 
    reflect _ = 0 
द्वारा

यह खराब होगा क्योंकि, उदाहरण के लिए,

reify (1 :: Int) $ \p -> reflect p 

कानूनी रूप से या तो 1 (सामान्य प्रतिबिंब प्रक्रिया के माध्यम से) या 0 (reify लागू करने से पहले पास किए गए फ़ंक्शन को विशेषज्ञता देकर) उत्पन्न कर सकता है।

हकीकत में, Data.Reflection में कुछ Reifies उदाहरणों को शामिल करने से यह विशेष शोषण अवरुद्ध प्रतीत होता है। मैंने जो बुराई उदाहरण वर्णित किया है उसे ओवरलैपिंग के रूप में खारिज कर दिया जाएगा। यदि अतिव्यापी उदाहरण सक्षम हैं, तो मेरा मानना ​​है कि अनिश्चितता ओवरलैपिंग लाए जाने से विशेषज्ञता को अवरुद्ध किया जा सकता है।

फिर भी, मैं सोच रहा हूं कि एक छायादार उदाहरण के साथ इसका खुलासा करने का कोई तरीका है, शायद जीएडीटी या कुछ ऐसे लोगों की मदद से।

उत्तर

4

मैं तात्कालिक रूप से कहता हूं कि यह जोखिम का जोखिम नहीं उठाता है। कुछ फेरबदल के बाद, सबसे अच्छा तरीका है मैं ऊपर आ सकता है reflect इस्तेमाल किया INCOHERENT का अपहरण करने के साथ है, जो आश्चर्य बेतरतीबी उपज के लिए पर्याप्त है: `SPECIALIZE` एक पर का उपयोग करके

{-# LANGUAGE 
    TypeFamilies, FlexibleInstances, MultiParamTypeClasses, 
    ScopedTypeVariables #-} 

import Data.Constraint 
import Data.Proxy 
import Data.Reflection 

instance {-# INCOHERENT #-} Reifies (s :: *) Int where 
    reflect _ = 0 

reflectThis :: forall (s :: *). Dict (Reifies s Int) 
reflectThis = Dict 

-- prints 0 
main = print $ 
    reify (1 :: Int) $ \(p :: Proxy s) -> 
    case reflectThis :: Dict (Reifies s Int) of 
    Dict -> reflect p 
+0

हममम ... मुझे आश्चर्य है अगर GHC धोखा दिया जा सकता है फ़ंक्शन अंततः 'पुनः प्राप्त' करने के लिए पारित किया। मैं कोशिश करता हूं कि जब मैं घर जाऊं। – dfeuer

+0

@ dfeuer क्या आपने कोशिश की? –

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