2015-10-05 8 views
6

unsafeVacuousData.Void.Unsafe और .# और #.Data.Profunctor.Unsafe दोनों में उन कार्यों का उपयोग करने के खतरों के बारे में चेतावनी दी गई है जो जीएडीटी हैं। कुछ खतरनाक उदाहरण स्पष्ट कर रहे हैं:बस जब असुरक्षित हैं, #।, और # असुरक्षित?

data Foo a where 
    P :: a -> Foo a 
    Q :: Foo Void 

instance Functor Foo where 
    fmap f (P x) = P (f x) 
    fmap f Q = P (f undefined) 

यहाँ, unsafeVacuous Q एक फर्जी प्रकार के साथ एक Q निर्माता का उत्पादन करेगा।

यह उदाहरण बहुत परेशान नहीं है क्योंकि यह एक समझदार Functor उदाहरण की तरह दूरस्थ रूप से भी नहीं दिखता है। क्या ऐसे उदाहरण हैं जो करते हैं? विशेष रूप से, क्या उन उपयोगी लोगों का निर्माण करना संभव होगा जो मज़ेदार/प्रोफेसर कानूनों का पालन करते हैं जब केवल अपने सार्वजनिक एपीआई का उपयोग करके छेड़छाड़ की जाती है, लेकिन इन असुरक्षित कार्यों के चेहरे में भयंकर रूप से टूट जाती है?

+3

उपरोक्त 'फू' के लिए मुझे लगता है कि कानून-पालन करने वाले मजेदार उदाहरण को तैयार करना असंभव है। मुझे आश्चर्य है कि किस प्रकार के जीएडीटी किसी को ऐसा करने की अनुमति देते हैं। ऐसा लगता है कि एक कन्स्ट्रक्टर 'K :: ... -> Foo T' किसी भी मज़ेदार उदाहरण को रोकता है जब तक कि' टी' एक प्रकार परिवर्तनीय न हो। (हो सकता है कि मैं कुछ दिख रहा हूं, यद्यपि ...) – chi

उत्तर

3

मुझे विश्वास नहीं है कि कोई सच्चा मज़ेदार है जहां unsafeVacuous कोई समस्या पैदा करेगा। लेकिन यदि आप एक खराब Functor लिखते हैं तो आप अपना खुद का unsafeCoerce बना सकते हैं, जिसका अर्थ है कि इसे {-# LANGUAGE Unsafe #-} के साथ लेबल करना चाहिए। an issue about it in void था।

यहाँ एक unsafeCoerce मैं

{-# LANGUAGE GADTs    #-} 
{-# LANGUAGE ScopedTypeVariables #-} 
{-# LANGUAGE TypeFamilies  #-} 
import Data.Void 
import Data.Void.Unsafe 

type family F a b where 
    F a Void = a 
    F a b = b 

data Foo a b where 
    Foo :: F a b -> Foo a b 

instance Functor (Foo a) where 
    fmap = undefined 

unsafeCoerce :: forall a b. (F a b ~ b) => a -> b 
unsafeCoerce a = (\(Foo b) -> b) $ (unsafeVacuous (Foo a :: Foo a Void) :: Foo a b) 

main :: IO() 
main = print $ (unsafeCoerce 'a' :: Int) 

जो 97 प्रिंट के साथ आया है।

+1

मॉड्यूल सीमा पर छिपाने के दौरान, 'एफएमएपी' अनुप्रयोगों को फ्यूज करने के लिए 'एफएमएपी' कन्स्ट्रक्टर होने के कारण धोखाधड़ी करने वाले मकानों का निर्माण करना संभव है। मैं ज्यादातर इस बारे में चिंतित हूं कि इस तरह के किसी भी शेंगेन को कुछ कम खतरनाक तरीके से जीएडीटी के साथ मिश्रित किया जा सकता है या नहीं। – dfeuer

+1

कुछ डेटा जैसे एफएमएपी एफ जहां एफएमएपी :: (एक्स -> ए) -> एफ एक्स -> एफएमएपी एफ ए'? इससे कोई समस्या नहीं आती है। यह केवल एक समस्या है जब आप विशेष रूप से 'शून्य' का अलग-अलग व्यवहार करते हैं (जैसे कि मेरे उदाहरण में)। मुझे उम्मीद नहीं है कि कोई गलती से ऐसा कर सकता है। जब तक सब कुछ मज़ेदार कानूनों को पूरा करता है, यह ठीक होना चाहिए। – cchalmers

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