2010-03-22 7 views
6

आसपास हास्केल के साथ एक सा खेलने के बाद मैं इस समारोह की ठोकर खाई:हास्केल की टाइप सिस्टम एक संख्यात्मक मान को फ़ंक्शन के रूप में मानती है?

Prelude Data.Maclaurin> :t ((+) . ($) . (+)) 
((+) . ($) . (+)) :: (Num a) => a -> (a -> a) -> a -> a 

(Data.Maclaurin पैकेज वेक्टर अंतरिक्ष से निर्यात किया जाता है।) तो यह एक अंक, एक समारोह, एक और अंक और अंत में रिटर्न लेता है एक संख्या क्या जादू निम्नलिखित काम करता है?

Prelude Data.Maclaurin> ((+) . ($) . (+)) 1 2 3 
6 

2 स्पष्ट रूप से कार्य नहीं है (a-> क) या मैं कुछ पर बाहर याद आती किया?

+0

http://www.haskell.org/haskellwiki/Num_instance_for_functions – sdcvvc

उत्तर

16

एक ही पैकेज defines एक Num उदाहरण के Data.NumInstances मॉड्यूल कार्यों कि संख्या लौटने के लिए:

instance Num b => Num (a->b) where 
    (+)   = liftA2 (+) 
    (*)   = liftA2 (*) 
    fromInteger = pure . fromInteger 
    ... 

हास्केल में एक पूर्णांक 2 तरह शाब्दिक सामान्य है इतना है कि यह Num के किसी भी उदाहरण के लिए एक नंबर का प्रतिनिधित्व कर सकते हैं:

Prelude> :t 2 
2 :: (Num t) => t 

से प्रकार एक विशिष्ट संदर्भ में आवश्यक है, fromInteger का एक वास्तविक संख्या के लिए यह परिवर्तित करने के लिएकक्षा कहा जाता है।

के बाद से सहायक मॉड्यूल ऊपर उल्लेख किया कार्यों के लिए Num का एक उदाहरण परिभाषित करता है, 2 अब fromInteger विधि वहाँ निर्दिष्ट के साथ एक समारोह में बदला जा सकता। तो ghci प्रश्न में निर्माण के दूसरे पैरामीटर के रूप में आवश्यक फ़ंक्शन प्राप्त करने के लिए fromInteger 2 पर कॉल करता है। तब पूरी अभिव्यक्ति 6 का मूल्यांकन करने के लिए होती है।

+0

इसके अलावा, * सभी * अनुप्रयोगी functors सांख्यिक कक्षाओं के लिए इन उदाहरणों स्वीकार करते हैं । जो भी आवेदक फंक्टर आप चाहते हैं उसके लिए ऐसे उदाहरणों को परिभाषित करने के लिए एक आसान तरीका के लिए [आवेदक-संख्या] (http://hackage.haskell.org/package/applicative-numbers) पैकेज देखें। – Conal

1

आपके पास भ्रमित होने का अच्छा कारण है। GHC में Data.NumInstances मॉड्यूल (जो Data.Maclaurin से भरी हुई है) का उपयोग करना यह एक निरंतर कार्य करने के लिए एक Num मजबूर करने के लिए संभव है।

Prelude Data.NumInstances> :t (2 :: (Num a) => a -> a) 
(2 :: (Num a) => a -> a) :: (Num a) => a -> a 
Prelude Data.NumInstances> (2 :: (Num a) => a -> a) 0   
2 
Prelude Data.NumInstances> (2 :: (Num a) => a -> a) 1000 
2 

अभिव्यक्ति के मूल्यांकन अनिवार्य रूप से, है,

((+) . ($) . (+)) 1 2 3 = ((+) . ($) . (1+)) 2 3 
         = ((+) (1+)) 2 3 
         -- (+) is defined for functions that return a Num 
         = ((+) (1+) (\_ -> 2)) 3 
         = ((+2) . (1+)) 3 
         = 6 
+2

नहीं, यह तब तक संभव नहीं है जब तक कि आपके पास कुछ गैर-मानक मॉड्यूल लोड न हों जो 'a -> a' के लिए 'न्यू' उदाहरण परिभाषित करते हैं। –

+1

खैर, अरे, मैं इसे डेटा के बिना काम करने की कसम खाता हूं। मैक्लोरिन लोड हो गया है, लेकिन ऐसा नहीं है। जैसा कि @sth बताता है, यह जादू Data.NumInstances द्वारा सक्षम है। –

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