2014-05-10 8 views
5

क्या जीएचसीआई में प्राथमिकता और सहयोगीता को एक समारोह खोजने का एक तेज़ और आसान तरीका है?जीएचसीआई में एक समारोह की प्राथमिकता और सहयोगीता को कैसे खोजा जाए?

मुझे पता चला है कि एक सीधी विधि विधि एक ऑपरेटर को एक दूसरे के साथ संयोजित करने के लिए है जब तक कि आपको प्राथमिकता पार्सिंग त्रुटि (पीपीई) प्राप्त न हो जाए। उदाहरण के लिए, !! की पूर्वता/संबद्धता की खोज के लिए, हम 0 ≤ n < 10 के लिए infix n के 10 विभिन्न ऑपरेटरों को परिभाषित कर सकते हैं:

>>> let infix 0 %; (%) = ($) 
>>> undefined % undefined !! undefined 
*** Exception: Prelude.undefined 
>>> let infix 1 %; (%) = ($) 
>>> undefined % undefined !! undefined 
*** Exception: Prelude.undefined 
[...] 
>>> let infix 8 %; (%) = ($) 
>>> undefined % undefined !! undefined 
*** Exception: Prelude.undefined 
>>> let infix 9 %; (%) = ($) 
>>> undefined % undefined !! undefined 

<interactive>:21:1: 
    Precedence parsing error 
     cannot mix `%' [infix 9] and `!!' [infixl 9] in the same infix expression 

त्रुटि बताता है कि predences और fixities हैं। चूंकि परिभाषित किए गए 10 कार्य गैर-सहयोगी हैं, इसलिए प्राथमिकता स्तर बराबर होने पर पीपीई से बचने का कोई मौका नहीं है। भरोसेमंद दृष्टिकोण प्रत्येक सहयोगीता के 10 कार्यों का प्रयास करना होगा, जो 20 का डब्ल्यूसीईटी दे रहा है (क्योंकि यदि आप लक्ष्य के समान सहयोगीता को शुरू करते हैं, तो उस सहयोगीता के साथ 10 गुजरेंगे, लेकिन फिर विफल होने के बाद विफलता होगी kth अगली एसोसिएटिविटी की प्राथमिकता, जहां k लक्ष्य फ़ंक्शन की प्राथमिकता है)।

लेकिन क्या कोई तेज़ तरीका है? मैं सोच आप औसतन लॉग (10) चरणों को प्राप्त करने के लिए उधार ले सकते हैं। उदाहरण के लिए, यदि लक्ष्य !!! था जिसे !! के रूप में परिभाषित किया गया है, लेकिन infixl 6 के साथ, हम (:[]) % "AB" !!! 1 अभिव्यक्ति कर सकते हैं, जहां % एक ही 10 डमी फ़ंक्शंस में से एक है। यदि % की पूर्वता एक पीपीई पैदा करने के लिए बहुत कम है, अभिव्यक्ति निकलेगा "B" (क्योंकि अभिव्यक्ति (:[]) % ("AB" !!! 1) को पार्स जाएगा) है, जबकि अगर पूर्वता बहुत अधिक है, यह निकलेगा (क्योंकि अभिव्यक्ति ((:[]) % "AB") !!! 1 को पार्स जाएगा)। उदाहरण:

>>> let infixl 6 !!!; (!!!) = (!!) 
>>> let infix 5 %; (%) = ($) 
>>> (:[]) % "AB" !!! 1 
"B" 
>>> --too low 
>>> let infix 7 %; (%) = ($) 
>>> (:[]) % "AB" !!! 1 
"*** Exception: Prelude.(!!): index too large 

>>> --too high 
>>> let infix 6 %; (%) = ($) 
>>> (:[]) % "AB" !!! 1 

<interactive>:10:1: 
    Precedence parsing error 
     cannot mix `%' [infix 6] and `!!!' [infixl 6] in the same infix expression 
>>> --got it 

हालांकि, मैं इस दृष्टिकोण के बारे में यकीन नहीं है।

  • आप मानसिक स्थिति जो संख्या के अगले अनुमान लगाना बनाए रख कर अपने सिर में विभाजन आदि करने के लिए
  • (कागज द्वारा/कैलकुलेटर शायद सिर्फ सरल तरीका में 10 कदम कर की तुलना में धीमी हो जाएगा) है
  • क्या यह पूरी तरह से सामान्य है? क्या आप हमेशा इस तरह एक परीक्षण अभिव्यक्ति बना सकते हैं?
  • मुझे यकीन नहीं है कि मैं हमेशा इस तरह की अभिव्यक्ति के साथ आ सकता हूं कि मैं केवल सरल विधि कर सकता हूं। इस मामले में यह वास्तव में तेजी से था, और मैं वास्तव में द्विभाजन विधि इससे पहले कि मैं सरल तरीका
  • पिछले चिंता मान्य रखता है के साथ आया था के साथ आया था, वहाँ एक पूरी तरह से सामान्य तरीके से स्वचालित रूप से इस का भाव उत्पन्न करने के लिए मौजूद है मेहरबान?

क्या किसी को वैकल्पिक विधि से अवगत है? मैं कल्पना कर सकता हूं कि एक ही चरण में ऐसा करने का कोई तरीका हो सकता है। लेकिन एक घंटे के बाद, सबसे अच्छा मैं इस उधार विधि के साथ आ सकता है।

उत्तर

15

हां। आप :info कमांड का उपयोग कर सकते हैं।

Prelude> :info (+) 
class Num a where 
    (+) :: a -> a -> a 
    ... 
     -- Defined in `GHC.Num' 
infixl 6 + 

Prelude> :info (.) 
(.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in `GHC.Base' 
infixr 9 . 

Prelude> :info ($) 
($) :: (a -> b) -> a -> b  -- Defined in `GHC.Base' 
infixr 0 $ 

यदि यह कहना नहीं है, यह infixl 9 के डिफ़ॉल्ट है।

+2

आप बस टाइप कर सकते हैं, उदाहरण के लिए, ': i + '। –

15

@kqr के जवाब स्पष्ट रूप से GHCi से सबसे अच्छा है, लेकिन मैं तो बस ध्यान दें जाएगा है कि वहाँ तुम क्या करने की कोशिश की करने के लिए इसी तरह की एक त्वरित तरीका है, जो मैं कभी कभी lambdabot साथ आईआरसी चैनल में उपयोग (जो का समर्थन नहीं करता :info)।

>>> (0$0 !!) 
क्योंकि वह (expr `op`) केवल तभी expr `op` var (expr) `op` var, साथ ही $ को हूबहू पार्स न्यूनतम स्थिरता का सही साहचर्य जा रहा है इस्तेमाल किया जा सकता खंड आवश्यकता के

, कि अभिव्यक्ति होगा कभी नहीं!! की स्थिरता की परवाह किए बिना पार्स, और आपको त्रुटि संदेश में !! की फ़िक्स्डिटी देगा।

+1

हम्म। मैं इसे उत्तर के रूप में स्वीकार करने के लिए प्रेरित हूं, क्योंकि यह 'प्राथमिकता' के विपरीत सभी प्राथमिकताओं (यहां तक ​​कि डिफ़ॉल्ट) के लिए भी काम करता है। याद रखने के लिए यह एक और बात है, लेकिन यह 'जानकारी' है। इसके अलावा 'जानकारी 'आपको डिफ़ॉल्ट प्राथमिकता/सहयोगीता को याद रखना है। – Dog

+0

@ डॉग: हां, डब्ल्यूसीईटी दोनों 1 हैं, लेकिन आपको 'जानकारी:' का उपयोग करने के लिए दो बार जितनी अधिक जानकारी याद रखना होगा। हालांकि, मैं दलील दूंगा कि यह * इसके लायक है * इसके बजाय 'जानकारी' याद रखें और डिफ़ॉल्ट फिक्सिटी 'infixl 9' है। बाद में तथ्य की आवश्यकता है यदि आप अपना खुद का हास्केल कार्यान्वयन लिख रहे हैं, तो आप इसे याद भी कर सकते हैं। एक बार जब आप हास्केल को लागू करने के लिए घूमते हैं तो यह एक अमूर्त बचत को प्रभावित करता है। इसके अलावा, 'जानकारी' अन्य उद्देश्यों के लिए उपयोगी है, जैसे किसी वर्ग के उदाहरण देखना, या यह पता लगाना कि मूल्य कहां परिभाषित किया गया है। –

+0

ठीक है, जब आप कुछ कोड पढ़ रहे हैं, तो आपको यह जानने के लिए सहयोगीता/प्राथमिकता पता होना चाहिए कि यह क्या करता है, इसलिए यह 'जानकारी' का उपयोग करने का एक और मामला है। – Dog

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