2014-08-28 7 views
10

क्या अभिव्यक्ति सरलीकरण से दर्द उठाने का कोई तरीका है?सीखना हास्केल - अभिव्यक्ति को सरल कैसे करें?

उदाहरण के लिए

, इस अभिव्यक्ति दी:

(+) <$> a <*> b $ 1 

मैं एक उपकरण है जो की व्याख्या करता है इसका क्या मतलब देखना पसंद करेंगे। यह शुरुआती के लिए काफी श्रमसाध्य है (पाने के स्रोतों में सही उदाहरण समारोह परिभाषा जाँच ऑपरेटर पूर्वता) शामिल सभी चरणों के साथ भाव सरल करने के लिए:

fmap (+) a <*> b $ 1 

Data.Functor

(.) (+) a <*> b $ 1 

में definition देखें instance Functor ((->) r) के लिए Control.Monad.Instances में fmap देखें

और इसी तरह।

संपादित करें: स्पष्टीकरण के लिए, मैं वास्तविक फ़ंक्शन परिभाषाओं का उपयोग करके अभिव्यक्ति को फिर से लिखने का एक तरीका ढूंढ रहा हूं ताकि नवागंतुक इस अभिव्यक्ति के परिणाम को समझ सके। (<$>) = fmap कैसे कहें? मुझे नहीं पता कि hoogle और अन्य टूल्स का उपयोग करके एक विशेष उदाहरण परिभाषा (स्रोत) कैसे खोजें।

संपादित करें: निम्न कटौती से मेल खाने के लिए गलत मूल अभिव्यक्ति बदल दी।

उत्तर

3

प्रारंभ GHCi, :cd स्रोत आप पढ़ रहे हैं, :load मॉड्यूल में आपकी रुचि है, और :i आदेश का उपयोग जानकारी प्राप्त करने के आधार निर्देशिका के लिए:

ghci> :i <$> 
(<$>) :: Functor f => (a -> b) -> f a -> f b 
    -- Defined in `Data.Functor' 
infixl 4 <$> 
ghci> :i $ 
($) :: (a -> b) -> a -> b -- Defined in `GHC.Base' 
infixr 0 $ 
ghci> :i . 
(.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in `GHC.Base' 
infixr 9 . 

कि आपको बताता है टाइप करें, जहां इसे परिभाषित किया गया है, एसोसिएटिविटी (infixl या infixr) और प्राथमिकता (संख्या; उच्चतर कठिन है)। तो (*10) <$> a $ 1 को ((*10) <$> a) $ 1 के रूप में पढ़ा गया है।

जब आप :load एक मॉड्यूल करते हैं, तो उस मॉड्यूल के अंदर दायरे में मौजूद सभी नाम ghci के अंदर दायरे में होंगे। एक जगह जहां यह परेशान हो सकता है यदि आपको कोड में कोई त्रुटि है, तो आप इसके अंदर कुछ भी :i नहीं कर सकते हैं। इन मामलों में, आप लाइनों पर टिप्पणी कर सकते हैं, undefined का उपयोग कर सकते हैं, और संभवत: टाइप किए गए छेद का उपयोग व्यवहार के रूप में भी करते हैं (अभी तक उन लोगों के साथ नहीं खेला है)।

जब आप इसमें हों, तो ghci में :? कमांड का प्रयास करें।

6

मुझे लगता है कि आसान तरीका GHCi 7.8 में typed holes उपलब्ध उपयोग करने के लिए है:

> (*10) <$> _a $ 1 
Found hole ‘_a’ with type: s0 -> b 
Where: ‘s0’ is an ambiguous type variable 
     ‘b’ is a rigid type variable bound by 
      the inferred type of it :: b at <interactive>:4:1 
Relevant bindings include it :: b (bound at <interactive>:4:1) 
In the second argument of ‘(<$>)’, namely ‘_a’ 
In the expression: (* 10) <$> _a 
In the expression: (* 10) <$> _a $ 1 

तो यह मुझे उस a :: s0 -> b बताता है। अगला ऑपरेटरों के आदेश यह पता लगाने की है:

> :i (<$>) 
(<$>) :: Functor f => (a -> b) -> f a -> f b 
infixl 4 <$> 
> :i ($) 
($) :: (a -> b) -> a -> b 
infixr 0 $ 

तो यह कहना है कि $ अत्यधिक राइट साहचर्य है, और यह देखते हुए इसे टाइप हम देखते हैं कि यह पहला तर्क चाहिए एक समारोह है होना है, तो a एक समारोह होना चाहिए (डबल पुष्टि)। इसका मतलब है कि (*10) <$> a $ 1((*10) <$> a) $ 1 जैसा ही है, इसलिए हम पहले (*10) <$> a पर ध्यान केंद्रित करेंगे।

> :t ((*10) <$>) 
((*10) <$>) :: (Num a, Functor f) => f a -> f a 
> :t (<$> _a) 
Found hole ‘_a’ with type: f a 
Where: ‘a’ is a rigid type variable bound by 
      the inferred type of it :: (a -> b) -> f b at Top level 
     ‘f’ is a rigid type variable bound by 
      the inferred type of it :: (a -> b) -> f b at Top level 
In the second argument of ‘(<$>)’, namely ‘_a’ 
In the expression: (<$> _a) 

तो हमें एक मजेदार होने के लिए a की आवश्यकता है। उपलब्ध उदाहरण क्या हैं?

> :i Functor 
class Functor (f :: * -> *) where 
    fmap :: (a -> b) -> f a -> f b 
    (<$) :: a -> f b -> f a 
     -- Defined in ‘GHC.Base’ 
instance Functor Maybe -- Defined in ‘Data.Maybe’ 
instance Functor (Either a) -- Defined in ‘Data.Either’ 
instance Functor ZipList -- Defined in ‘Control.Applicative’ 
instance Monad m => Functor (WrappedMonad m) 
    -- Defined in ‘Control.Applicative’ 
instance Control.Arrow.Arrow a => Functor (WrappedArrow a b) 
    -- Defined in ‘Control.Applicative’ 
instance Functor (Const m) -- Defined in ‘Control.Applicative’ 
instance Functor [] -- Defined in ‘GHC.Base’ 
instance Functor IO -- Defined in ‘GHC.Base’ 
instance Functor ((->) r) -- Defined in ‘GHC.Base’ 
instance Functor ((,) a) -- Defined in ‘GHC.Base’ 

तो (->) r है, जो भयानक है क्योंकि हम जानते हैं a एक समारोह हो गया होता है। Num बाधा से, हम निर्धारित कर सकते हैं कि rNum a => a जैसा ही होना चाहिए। इसका मतलब है कि (*10) <$> a :: Num a => a -> a। उस से हम 1 पर लागू होते हैं, और हमें (*10) <$> a $ 1 :: Num a मिल जाएगा, जहां a कुछ अज्ञात कार्य है।

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

5

जीएचसीआई अद्भुत और सही ढंग से सुझाव दिया गया था, और मैं इसे भी सुझाव देता हूं।

मैं भी Hoogle सुझाव देने के लिए, (इसके लिए एक बटन सही पर शीर्ष साइडबार पर) त्वरित खोज के साथ सक्षम है क्योंकि, तुम बहुत तेजी से काम करता है लिए खोज सकते हैं, यह बहुत प्रदान कर सकते हैं, चाहते हैं ज्यादा जीएचसीआई की तुलना में अधिक जानकारी, और सबसे अच्छा हिस्सा यह है कि आपको में खोजने के लिए मॉड्यूल का उल्लेख नहीं करना है। (Haskell.org साइट से)

ghci> :t pure 
<interactive>:1:1: Not in scope: ‘pure’ 
ghci> :m +Control.Applicative 
ghci> :t pure 
pure :: Applicative f => a -> f a 

ऊपर Hoogle लिंक में से एक है: यह है जहाँ आप पहले आयात करने के लिए है GHCi के विपरीत है। होगल एक प्रोग्राम है जिसे आप अपनी मशीन (cabal install hoogle) पर भी इंस्टॉल कर सकते हैं और कमांड लाइन (hoogle your-query) से क्वेरी निष्पादित कर सकते हैं।
सिडेनोट: आपको पहले जानकारी एकत्र करने के लिए hoogle data चलाने की आवश्यकता होगी। इसके लिए wget/curl की आवश्यकता है, इसलिए यदि आप विंडोज़ पर हैं तो आपको शायद अपने पथ में this प्राप्त करना होगा (या निश्चित रूप से विंडोज़ के लिए एक कर्ल)। लिनक्स पर यह लगभग हमेशा निर्मित होता है (यदि आपके पास लिनक्स पर नहीं है, तो बस apt-get इसे)। मैं कभी भी कमांड लाइन से Hoogle का उपयोग नहीं करता, यह बस इतना सुलभ नहीं है, लेकिन यह अभी भी बहुत उपयोगी हो सकता है क्योंकि कुछ टेक्स्ट-एडिटर्स और उनके प्लगइन्स इसका लाभ उठा सकते हैं।

वैकल्पिक रूप से आप FPComplete's Hoogle का उपयोग कर सकते हैं जो कभी-कभी अधिक संतोषजनक होता है (क्योंकि मेरे अनुभव में यह अधिक तृतीय पक्ष पुस्तकालयों से अवगत है। मैं इसे केवल "हुगलिंग सत्र" में उपयोग करता हूं)।

रास्ते में Hayoo! भी है।

Hoogle में आप शायद> समय का 95% यह करने के लिए +Module एक मॉड्यूल किसी कारण से यदि इसके लिए खोजा जा रहा नहीं कर रहा है (इस स्थिति 3 पार्टी पुस्तकालयों के लिए कभी कभी) आयात करने की जरूरत नहीं होगी, लेकिन ।
आप -Module द्वारा मॉड्यूल को भी फ़िल्टर कर सकते हैं।
उदाहरण के लिए: destroyTheWorld +World.Destroyer -World.Destroyer.MercydestroyTheWorld खोजने के लिए और सुनिश्चित करें कि आप यह करने के लिए दयालु रास्ता पर नहीं देख रहे हैं बनाने के लिए (यह Data.ByteString & Data.ByteString.Lazy में विभिन्न संस्करणों के लिए एक ही समारोह के नाम, लोगों की तरह साथ मॉड्यूल के साथ बहुत आसान बात आती है, Data.Vector & Data.Vector.Mutable, आदि)।

ओह और होगल का एक और शानदार लाभ यह है कि न केवल यह आपको फ़ंक्शन के हस्ताक्षर दिखाता है, यह आपको मॉड्यूल के हैडॉक पृष्ठों पर भी ले जा सकता है, इसलिए आप उन पृष्ठों में दस्तावेज़ + प्राप्त भी कर सकते हैं, जब आप उपलब्ध हों, तो आप क्लिक कर सकते हैं प्रत्येक समारोह के दाईं ओर "स्रोत" पर यह देखने के लिए कि इसे और भी जानकारी के लिए कैसे कार्यान्वित किया जा रहा है।

यह प्रश्न के दायरे से बाहर है, लेकिन होगल का उपयोग फ़ंक्शन हस्ताक्षरों के लिए पूछताछ करने के लिए भी किया जाता है जो कि केवल दिमाग में मददगार है। अगर मुझे एक ऐसा फ़ंक्शन चाहिए जो इंडेक्स नंबर और एक सूची लेता है और मुझे उस इंडेक्स में तत्व देता है, और मुझे आश्चर्य है कि यह पहले से ही बनाया गया है, तो मैं इसे सेकंड के भीतर खोज सकता हूं।
मुझे पता है कि फ़ंक्शन एक संख्या और एक सूची लेता है, और मुझे सूची का एक तत्व देता है ताकि फ़ंक्शन हस्ताक्षर इन पंक्तियों के साथ कुछ दिखाना चाहिए: Int -> [a] -> a (या सामान्य रूप से: Num a => a -> [b] -> b), और दोनों उदाहरण दिखाते हैं कि वास्तव में वास्तव में है उस के लिए एक समारोह ((!!) और genericIndex)।

जहां जीएचसीआई का ऊपरी भाग है कि आप अभिव्यक्तियों के साथ खिलौना कर सकते हैं, उन्हें तलाश सकते हैं, आदि। अमूर्त कार्यों से निपटने के दौरान कई बार इसका मतलब है।
:l (ओड) में सक्षम होने के नाते बहुत उपयोगी है।

यदि आप केवल फ़ंक्शन हस्ताक्षर ढूंढ रहे हैं, तो आप होगल और जीएचसीआई दोनों को जोड़ सकते हैं।
जीएचसीआई में आप :! cmd टाइप कर सकते हैं, और जीएचसीआई कमांड लाइन में cmd निष्पादित करेगा, और परिणाम प्रिंट करेगा। इसका मतलब है कि आप भी जीएचसीआई के अंदर होगल कर सकते हैं, उदा। :! hoogle void

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