2012-08-03 9 views
7

के साथ "अनुमान नहीं किया जा सका" त्रुटि जब मैं इस संकलन करने का प्रयास करें:हास्केल: runST

module Main where 

import qualified Data.Vector.Unboxed.Mutable as MV 
import Control.Monad.ST 

myRead mv = runST $ MV.read mv 0 

मैं निम्न त्रुटि संदेश मिलता है:

Could not deduce (t ~ U.MVector s a) 
    from the context (U.Unbox a) 
     bound by the inferred type of myRead :: U.Unbox a => t -> a 
     at src/Main.hs:53:1-32 
     `t' is a rigid type variable bound by 
      the inferred type of myRead :: U.Unbox a => t -> a 
      at src/Main.hs:53:1 
    Expected type: U.MVector (PrimState (ST s)) a 
     Actual type: t 
    In the first argument of `MV.read', namely `mv' 
    In the second argument of `($)', namely `MV.read mv 0' 
    In the expression: runST $ MV.read mv 0 

मैं एक परिवर्तनशील वेक्टर से पढ़ने बना सकते हैं रनस्ट के साथ शुद्ध? यदि हां, तो कैसे? मुझे लगता है कि यह myRead के लिए एक प्रकार के हस्ताक्षर में शामिल है, लेकिन मैंने जो भी कोशिश की है, वह सिर्फ अधिक से अधिक समझ में त्रुटि संदेशों का कारण बनता है।

संपादित: कुछ संदर्भ मैं सिर्फ नीचे एक टिप्पणी में डाल उजागर: संदर्भ यहाँ, कि मैं एक समारोह है कि एक परिवर्तनशील वेक्टर में लेता है एक अस्थायी खरोंच स्पेस दें, फिर जरूरतों के रूप में परिवर्तनशील वेक्टर का उपयोग कर कुछ संगणना करता है एक फ्लोट वैल्यू वापस करने के लिए। क्योंकि मुझे म्यूटेबल वेक्टर में हुए बदलावों की परवाह नहीं है, इसलिए मैं सोच रहा था कि क्या इसके "राज्य परिवर्तन" को अनदेखा करने का कोई तरीका है और बस इसके अंदर से मूल्यों में से एक को वापस कर दें।

+1

मुझे लगता है कि बुद्धिमानों की राय, जैसे ब्रेटनर और फिशर, यह है कि हमें इस बिंदु पर आप कैसे पहुंचे इस बारे में और जानना होगा। म्यूटेबल वेक्टर का उत्पादन करने का क्या काम है जो आप मेरे रीड को लागू करने का प्रस्ताव देते हैं? Breitner की प्रतिक्रिया में अंतिम वाक्य देखें। अगर हम जानते थे कि आपको इस कोने में क्या रखा गया था, तो हम कह सकते हैं कि चीजों का दोबारा विश्लेषण कैसे करें ताकि वे एक साथ लटका सकें। इस प्रकार कोड की कुछ और पंक्तियां सहायक होंगी। उदाहरण के लिए, यदि 'एमवी' एसटी ब्लॉक के अंदर है, तो सरल परिभाषा' myRead mv = mV.read mv 0' (no 'runST') का उपयोग नहीं किया जा सकता है। – applicative

+0

मुझे आवेदक ने जो कहा है उसे मजबूत करने दें: हमें अधिक संदर्भ की आवश्यकता है। यह जानने के बिना कि आप वास्तव में क्या हासिल करना चाहते हैं, हम उचित समाधान नहीं ढूंढ सकते हैं। –

उत्तर

2

अन्य उत्तरों अच्छे हैं, लेकिन मुझे लगता है कि एसटी के बारे में एक मूल बात है जो आप गायब हैं। रनस्ट के लिए प्रत्येक कॉल प्रभावी रूप से एक नया "एसटी ब्रह्मांड" बना रहा है जिसमें कुछ अनिवार्य कोड चलता है। इसलिए यदि आपके पास सरणी बनाने के लिए रनस्ट करने के लिए एक कॉल है और उस सरणी से मूल्य प्राप्त करने के लिए रनस्ट को एक अलग कॉल करने के लिए, चीजें संभवतः काम नहीं कर सकती हैं। दो रनस्ट कॉल अपने अद्वितीय सार्वभौमिक चाहते हैं, जबकि आप उन्हें एक साझा करना चाहते हैं।

कुछ विवरणों में क्या जवाब समझाया गया है यह है कि इन अद्वितीय सार्वभौमिकों को कुछ प्रकार-सिस्टम चालबाजी द्वारा कैसे बनाया जाता है।

+0

यह। 'runST' को बाहर से शुद्ध दिखना चाहिए, और इसलिए कुछ भी परिवर्तनीय' एसटी 'मोनैड से बच नहीं सकता है। – MathematicalOrchid

3

संकलक mv को कुछ विशिष्ट प्रकार के रूप में बाईं तरफ तर्क mv देखने के लिए डिफ़ॉल्ट है, लेकिन दाईं ओर पॉलिमॉर्फिक प्रकार की कुछ आवश्यकता है। एक प्रकार का हस्ताक्षर चीजों को ठीक कर सकता है।

{-#LANGUAGE Rank2Types#-} 
module Main where 

import qualified Data.Vector.Unboxed.Mutable as MV 
import Control.Monad.ST 

myRead :: MV.Unbox a => (forall s . MV.MVector s a) -> a 
myRead mv = runST $ MV.read mv 0 

जिनमें आप समारोह के हस्ताक्षर होने कुछ इस तरह होगा, अगर मैं समझता हूँ:

-- myBadRead :: forall s a . MV.Unbox a => MV.MVector s a -> a 
-- myBadRead mv = runST $ MV.read mv 0 

लेकिन यहाँ runST :: (forall s. ST s a) -> a पर काम करने के लिए एक s स्वतंत्र बात नहीं होती, s के बाद से जब आप एलएचएस पर mv लिखते हैं तो तय किया जाता है।

संपादित करें: हालांकि, जोआचिम बी और डैनियल एफ पर बल दिया गया है, हालांकि उपरोक्त परिभाषा सुसंगत है, लेकिन अभ्यास में इसका कोई उपयोग नहीं होगा, क्योंकि आप इसे देने के लिए वेक्टर mv बनाने में सक्षम नहीं होंगे। इसे क्रुद्ध रूप से रखने के लिए, mv उत्पन्न करने का कोई भी तरीका पहले से ही s को संकलक द्वारा हुड के तहत सौंपा गया होगा। एक मानक तरीका दाहिने हाथ की ओर तो Data.Vector.Unboxed से एक 'शुद्ध' वेक्टर पर इस तरह के एक समारोह में कार्य करने के लिए,, .Mutable मॉड्यूल

import qualified Data.Vector.Unboxed as UV 
import qualified Data.Vector.Unboxed.Mutable as MV 
import Control.Monad.ST 

myRead :: MV.Unbox a => UV.Vector a -> a 
myRead v = runST $ do mv <- UV.unsafeThaw v 
         MV.read mv 0 
बेशक

से आपरेशन लागू करने से पहले यह पिघलना है, इस विशेष परिभाषा बराबर है myRead = (UV.! 0) इसी तरह करने के लिए, कुछ इस तरह मतलब होता है, myRead

mhead :: MV.Unbox a => MV.MVector s a -> ST s a 
mhead mv0 = MV.read mv0 0 

mrx = runST $ do mv <- UV.unsafeThaw $ UV.enumFromStepN 0 1 20 
          -- ^^^ or however the mv is generated. 
        x <- MV.unsafeRead mv 17 -- arbitrary 'scratch pad' 
        MV.unsafeWrite mv 17 (2*x) -- computations 
        mhead mv 
        -- ^^^ we return just the first element, after all the mutation 

की परिभाषा में runST हड़ताली यहाँ, बजाय runST साथ myRead या mhead बंद बंद करने हम मैं रखना s में टी polymorphic और फिर उसी ST ब्लॉक के अंदर इसका उपयोग कर सकते हैं जिसमें परिवर्तनीय वेक्टर mv प्रकट होता है। इस प्रकार संकलक 'गुप्त' s का उपयोग करने में सक्षम होंगे, जो mhead को mv पर लागू करने के परिणाम की व्याख्या करने के लिए संपूर्ण रूप से डू-ब्लॉक के लिए उपयोग कर रहा है, क्योंकि यह mhead

की हमारी बहुलक परिभाषा द्वारा खोले गए संभावनाओं में से एक है
3

आवेदक द्वारा उत्तर आपको संकलित करने के लिए अपना कोड कैसे प्राप्त करें, बताता है। लेकिन कोड प्रयोग योग्य नहीं होगा: runST का बिंदु यह है कि अनिवार्य गणना बाध्य प्रकार चर के कारण अनिवार्य गणना इसे से नहीं बचा सकती है।

अब किसी भी परिवर्तनशील सरणी है कि आप कहीं बनाने के एक तय रों के लिए प्रकार MVector s a होगा, जबकि अपनी myRead कि किसी भी रों के लिए एक वेक्टर प्रदान करता है एक मूल्य की उम्मीद है।

ऐसा लगता है कि पहले एक समस्या है जिससे आप उस (असंभव) कार्य को प्राप्त करना चाहते हैं।

+0

मैं मानता हूं कि यह एक अवांछित कार्य है, मैं प्रकार त्रुटि की व्याख्या करने की कोशिश कर रहा था। क्या स्पष्टीकरण अक्षम है? यदि ऐसा है तो मुझे इसे हटा देना चाहिए। मैं लेखक के बारे में सोच रहा था कि एसटी के साथ कैसे प्रकार का अनुमान काम करता है। – applicative

+0

@ एप्प्लिकेटिव नहीं, स्पष्टीकरण ठीक है। शायद यह भी जोड़ें कि फ़ंक्शन अनुपयोगी होगा, ताकि दोनों उत्तरों में यह महत्वपूर्ण तथ्य हो। –

+0

मैं यह नहीं कह सकता कि मैंने ऊपर जो कुछ कहा है, मैंने उसे समझा है, हालांकि, मैं सोच रहा था कि क्या आप आगे बता सकते हैं कि यह कार्य असंभव क्यों है। संदर्भ यह है कि मेरे पास एक ऐसा कार्य है जो एक परिवर्तनीय वेक्टर में लेता है, अस्थायी स्क्रैच स्पेस के रूप में म्यूटेबल वेक्टर का उपयोग करके कुछ कंप्यूटेशंस करता है, फिर उसे फ्लोट वैल्यू वापस करने की आवश्यकता होती है। क्योंकि मुझे म्यूटेबल वेक्टर में हुए बदलावों की परवाह नहीं है, इसलिए मैं सोच रहा था कि क्या इसके "राज्य परिवर्तन" को अनदेखा करने का कोई तरीका है और बस इसके अंदर से मूल्यों में से एक को वापस कर दें। – brooks94