मुझे लगता है कि आसान तरीका 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
बाधा से, हम निर्धारित कर सकते हैं कि r
Num a => a
जैसा ही होना चाहिए। इसका मतलब है कि (*10) <$> a :: Num a => a -> a
। उस से हम 1
पर लागू होते हैं, और हमें (*10) <$> a $ 1 :: Num a
मिल जाएगा, जहां a
कुछ अज्ञात कार्य है।
यह टाइप किए गए छेद के साथ :t
और :i
का उपयोग करके जीएचसीआई का उपयोग करके खोजने योग्य है। निश्चित रूप से, इसमें शामिल कदमों की एक उचित संख्या है, लेकिन जब आप एक जटिल अभिव्यक्ति को तोड़ने की कोशिश कर रहे हैं तो यह कभी विफल नहीं होता है, बस विभिन्न उप-अभिव्यक्तियों के प्रकारों को देखें।