2012-02-28 12 views
5

निम्नलिखित कार्यक्रम प्रकार जांच करता है कि मैं कमांड लाइन (जैसे ghci file.hs) पर यह निर्दिष्ट करें:ghci - इंटरैक्टिव मोड में उत्सुक संकलन?

Prelude> import Data.Ratio 
Prelude Data.Ratio> let x = [1..] 
Prelude Data.Ratio> let y = (1%2) + (head x) 
<interactive>:1:23: 
    Couldn't match expected type `Ratio a0' with actual type `Integer' 

यह:

import Data.Ratio 
foo = let x = [1..] 
      y = (1%2) + (head x) 
     in y 

हालांकि, अगर मैं इसे सहभागी प्रवेश मैं एक प्रकार त्रुटि मिलेगी ऐसा लगता है कि को अधिक सामान्य (Num t, Enum t) => [t] के विपरीत [Integer] के रूप में उत्सुकता से टाइप किया जा रहा है।

क्या मैं इसके बारे में कुछ भी कर सकता हूं? क्या ऐसी अन्य स्थितियां हैं जहां बैच मोड से इंटरैक्टिव मोड अलग होगा?

let x = [1..] :: [Ratio Int] 

के रूप में:

+1

Monomorphism प्रतिबंध ... – augustss

+1

और वास्तव में दोषी – Ptival

+3

लिखते हैं, तो खतरनाक monomorphism प्रतिबंध नहीं है। इसके चार तरीके हैं: स्पष्ट हस्ताक्षर दें या इस प्रतिबंध को बंद करें (जीएचसीआई में, आप 'सेट -XNoMonomorphismRestriction' कर सकते हैं और आप कर चुके हैं; भाषा pragmas और कंपाइलर झंडे भी काम करते हैं)। – Vitus

उत्तर

10

बाइंडिंग, यानी प्रपत्र x = ... के उन लोगों के अधीन हैं monomorphism restriction, जिसका अर्थ है कि जीएचसी किसी भी प्रकार की जानकारी उपलब्ध कराने के लिए गैर-पॉलीमोर्फिक बनाने की कोशिश करेगा, और किसी भी amb को हल करने के लिए type defaulting पर वापस गिर जाएगी iguities। (असल में, जीएचसीआई a slightly more permissive set of defaulting rules का उपयोग करता है, लेकिन यह वास्तव में इस प्रश्न के लिए कोई फर्क नहीं पड़ता)।

चूंकि let x = [1..] लिखते समय कोई अन्य प्रकार की जानकारी उपलब्ध नहीं है, इसलिए टाइपिंग को [Integer] के रूप में अनुमानित करने का कारण बनता है, क्योंकि Integer डिफ़ॉल्ट संख्यात्मक प्रकार है।

  1. एक प्रकार हस्ताक्षर का उपयोग करें:

    इस समस्या को हल करने के कई तरीके हैं। यह हमेशा काम करता है, लेकिन जटिल प्रकारों के साथ काम करते समय कभी-कभी थकाऊ हो सकता है।

    > let x = [1..] :: [Rational] 
    
  2. तर्क के साथ बंधन लिखें। यह आपके मामले में लागू नहीं होता है, लेकिन आप कभी-कभी बिंदु-मुक्त फ़ंक्शन परिभाषा लिखते समय यह समस्या देखते हैं।

    > let f = (+) 
    > :t f 
    f :: Integer -> Integer -> Integer 
    > let f x y = x + y 
    > :t f 
    f :: Num a => a -> a -> a 
    
  3. प्रकार चेकर और अधिक जानकारी दें। आपके मामले में हम एक let कथन में दोनों बाइंडिंग लिखकर समस्या से बच सकते हैं। जीएचसी फिर दूसरी बाध्यकारी से प्रकार की जानकारी का सही ढंग से अनुमान लगा सकता है कि x में [Rational] टाइप होना चाहिए।

    > let x = [1..]; y = 1%2 + head x 
    > :t x 
    x :: [Ratio Integer] 
    
  4. monomorphism प्रतिबंध अक्षम करें। यदि आप कुछ प्रकार के उदाहरण की अपेक्षा कर रहे थे तो इसका गंभीर प्रदर्शन प्रभाव हो सकता है। एक Integer, जबकि यह वास्तव में Num a => a है, क्योंकि बाद वाले को साझा किए जाने पर प्रत्येक बार पुन: संकलित किया जाना चाहिए। यह मुख्य कारण है कि प्रतिबंध पहली जगह क्यों मौजूद है।

    हालांकि, दुभाषिया में यह आमतौर पर एक समस्या से कम होता है, इसलिए सुविधा अक्सर इसके लायक होती है।

    > :set -XNoMonomorphismRestriction 
    > let x = [1..] 
    > :t x 
    x :: (Num t, Enum t) => [t] 
    

    आप डिफ़ॉल्ट रूप से इस पर चाहते हैं, तो आप इसे अपने .ghci file को जोड़ सकते हैं।

4

आप निम्नलिखित होने की x को परिभाषित करते हुए इसके बारे में कुछ कर सकते हैं तर्क के बिना

Data.Ratio Prelude> let x = [1..] :: [Ratio Int] 
Data.Ratio Prelude> let y = (1%2) + (head x) 
Data.Ratio Prelude> y 
3 % 2 
Data.Ratio Prelude> 
+1

मैं दृढ़ता से 'अनुपात Int' का उपयोग करने के खिलाफ सलाह देता हूं, जब तक कि आप पूरी तरह से सकारात्मक रूप से नहीं जानते कि आपकी गणना अधिक नहीं हो सकती है और आप प्रदर्शन के लिए बेताब हैं - और फिर भी मुझे यह पसंद नहीं है। मेरी राय में 'अनुपात' को एक पॉलिमॉर्फिक प्रकार बनाने में एक गलती हुई थी, यहां तक ​​कि छोटी गणना भी 64 बिट्स से अधिक हो सकती है, और फिर आपको पूर्ण बकवास मिलता है। –

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