2013-09-12 10 views
7

का कारण बनता है जब मैं GHC 7.4.1 के अंतर्गत निम्नलिखित कोड को लोड करने का प्रयास करें:newtype प्रकार की त्रुटि

{-# LANGUAGE RankNTypes #-} 

import Control.Monad.ST 

newtype M s a = M { unM :: ST s a } 

runM :: (forall s. M s a) -> a 
runM (M m) = runST m 

यह निम्न संदेश के साथ विफल रहता है:

test.hs:9:14: 
    Couldn't match type `s0' with `s' 
     because type variable `s' would escape its scope 
    This (rigid, skolem) type variable is bound by 
     a type expected by the context: ST s a 
    The following variables have types that mention s0 
     m :: ST s0 a (bound at test.hs:9:9) 
    In the first argument of `runST', namely `m' 
    In the expression: runST m 
    In an equation for `runM': runM (M m) = runST m 

ऐसा क्यों असफल होता है, जब MST के आसपास सिर्फ एक रैपर है?

(। मेरे वास्तविक कार्यक्रम शीर्ष – पर खड़ी कुछ ट्रांसफार्मर यह सिर्फ एक न्यूनतम मामला है)


संपादित:

runM m = let M m' = m in runST m 
: यह एक let फिक्स मुद्दा जोड़ने लगता है

हालांकि, अगर TypeFamilies सक्षम है (जैसा कि यह मेरे वास्तविक कोड में है), यह फिर से विफल हो जाता है।

+0

मुझे विश्वास है कि ऐसा इसलिए है क्योंकि – jozefg

+0

क्या है? –

+0

क्षमा करें, मैंने अपनी खुद की परिकल्पना को अस्वीकार कर दिया :( – jozefg

उत्तर

11

यह पैटर्न मैचों + रैंकनटाइप के साथ एक समस्या है।

GHC infers m प्रकार ST ??? a जहां ??? एक प्रकार चर कि कुछ भी साथ एकजुट है और कुछ के साथ एकजुट करने के लिए है सकते हैं * है है। तो हम इसे runST और runST के साथ पास करते हैं ST s a चाहता है ताकि m इसके साथ एकीकृत हो और ???s के साथ एकीकृत हो। लेकिन प्रतीक्षा करें, अब हम s के दायरे के बाहर एकजुट हो रहे हैं जहां s को इस तरह के आपदा को परिभाषित किया गया है।

एक सरल उदाहरण

test (M m) = (m :: forall t . ST t a) `seq`() 

है और फिर हम एक ही त्रुटि मिलती है क्योंकि हम mt का उपयोग कर के प्रकार के साथ एकजुट करने के लिए प्रयास करते हैं, लेकिन t बहुत छोटा एक दायरे में है।

सरल समाधान बस

test m = runST (unM m) 

यहाँ unM रिटर्न एक अच्छे और सच्चे runST के साथ खुश है बहुरूपी ST उस के साथ इस प्रकार के चर बनाने के लिए नहीं है। आप let का उपयोग कर सकते हैं क्योंकि यह डिफ़ॉल्ट पॉलीमोर्फिक है लेकिन -XTypeFamilies से मोनोमोर्फ़िक होने से यह आपके द्वारा खोजे गए पैटर्न मिलान की तरह ही उड़ाएगा।


** ऐसा लगता है कि m मोनोमोर्फिक है। let पॉलिमॉर्फिक प्रकार के परिवारों के बिना है, इसलिए मुझे संदेह है कि यह क्या हो रहा है। यह

test :: forall a. (forall t. M t a) ->() 
test (M m) = (m :: ST Bool a) `seq` (m :: ST Int a) `seq`() 

त्रुटियाँ तरह Bool और Int को एकजुट करने के रूप में आप एक monomorphic प्रकार चर से उम्मीद होती है की कोशिश कर रहा व्यवहार करता है। मुझे लगता है कि प्रत्येक अजीब प्रकार की त्रुटि क्यों मोनोमोर्फिक प्रकार परिवर्तक के कुछ रूप छिपाने लगती है ..

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