2011-01-19 14 views
5

में अग्रदूत के शुरुआती/शिक्षार्थी कार्यान्वयन मैं मोर्फिज्म परिभाषा और पैटर्न मिलान की मेरी समझ का परीक्षण करने के लिए एक foreach morphism को लागू करने की कोशिश कर रहा हूं ... जाहिर है, मैं दोनों बिंदुओं को पूरी तरह से याद करता हूं।हैकेल

क्या आप मुझे सही कर सकते हैं? मैं की सूची लेने के लिए a और मॉर्फिज्म f की सूची लेने के लिए और f के r सभी a तत्वों पर लागू होने के लिए मॉर्फिज्म foreach की सूची लेना चाहता हूं।

foreach :: [a] → f → [r] 
foreach [] f = [] 
foreach x:[] f = (f x):[] 
foreach []:x f = []:(f x) 
foreach (x:xs) f = (f x) : (foreach (xs f)) 

src\Main.hs:23:0: Parse error in pattern

+3

वैसे: यह पहले से मौजूद है, जिसे 'मानचित्र' कहा जाता है और आधे लाइनों में परिभाषित किया जाता है। – delnan

+0

@ डेलनान: इस तरह के तर्कों के साथ, इसे 'for' कहा जाता है (और संभवतः 'मानचित्र' के संदर्भ में परिभाषित किया गया है)। –

+0

@Alexandre: आह हाँ, तर्क आदेश को अनदेखा किया गया ... परिभाषा 'फ्लिप मानचित्र' होगी। – delnan

उत्तर

12

समस्या है yntactic, इस पंक्ति में:

foreach x:[] f = (f x):[] 

पैटर्न में कन्स्ट्रक्टर एप्लिकेशन को आमतौर पर संश्लेषित करने की आवश्यकता होती है। यह काम करेगा:

foreach (x:[]) f = (f x):[] 
संयोग

... इसलिए दूसरी ओर आप दाएँ हाथ की ओर पर कोष्ठकों की जरूरत नहीं है समारोह आवेदन, सर्वोच्च प्राथमिकता है:

foreach (x:[]) f = f x:[] 

ऊपर के लिए रखती है किसी भी इन्फ़िक्स निर्माता, लेकिन एक अंतिम नोट के रूप में, विशेष रूप से सूचियों के लिए वहाँ एक विशेष वाक्य रचना है:

foreach [x] f = [f x] 

अपने कोड के साथ अन्य मुद्दों कर रहे हैं के रूप में यह खड़ा है, लेकिन है कि तत्काल त्रुटि है। अन्य समस्याओं के एक त्वरित अवलोकन:

foreach :: [a] → f → [r] 

प्रकार चर परोक्ष सार्वभौमिक मात्रा निर्धारित कर रहे हैं, तो इसका मतलब यह है किसी भी प्रकार f। आपको एक और विशिष्ट प्रकार की आवश्यकता है, अर्थात् a -> r

foreach x:[] f = (f x):[] 

यह अनावश्यक है - पुनरावर्ती मामले को सही ढंग से यहाँ काम करेंगे, x करने के लिए f लागू करने और पूंछ पर ही बुला, खाली सूची मामले दे रही है। इस खाली सूची [] के खिलाफ एक सूची के सिर मिलान पैटर्न है, जिसका अर्थ है कि समारोह सूचियों की एक सूची पर काम कर रहा है -

foreach []:x f = []:(f x) 

मैं इसका मतलब यह है कि आप क्या सोचते तो इसका मतलब है नहीं लगता।

foreach (x:xs) f = (f x) : (foreach (xs f)) 

यहां कोष्ठक या तो अनावश्यक या गलत हैं। फिर, : जैसे ऑपरेटरों की तुलना में फ़ंक्शन एप्लिकेशन की उच्च प्राथमिकता है। इसके अतिरिक्त, (xs f) का अर्थ xs से f पर लागू करना है, जैसे कि यह एक कार्य था।foreach को दो तर्कों के लिए लागू करने के लिए, बस foreach xs f पर्याप्त होगा।


तुलना के लिए, यहाँ मानक पुस्तकालय समारोह map (तर्क आदेश को छोड़ कर एक) के लिए स्रोत कोड है:

map :: (a -> b) -> [a] -> [b] 
map _ []  = [] 
map f (x:xs) = f x : map f xs 
+0

thx tearfully tolesfully, अर्थात् उच्च प्राथमिकता के साथ समारोह आवेदन। –

+0

और नक्शा –

2

आप foreach []:x f = []:(f x) में () लगाना भूल गया है और गलत तरीके से निर्दिष्ट समारोह प्रकार जब संकलित, मैं है, निम्नलिखित अब संकलन करना चाहिए:

foreach :: [a] -> (a -> r) -> [r] 
foreach [] f = [] 
foreach (x:[]) f = (f x):[] 
foreach (x:xs) f = (f x) : (foreach xs f) 

और चलाएँ:

*Main> foreach [1..20] (+1) 
[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21] 
+0

'(ए -> आर) 'यहां का अर्थ है कि' foreach' के लिए दूसरा तर्क वह फ़ंक्शन है जो टाइप 'ए' को' r' टाइप करने के लिए परिवर्तित करता है। यदि आप उदाहरण के लिए निर्दिष्ट फ़ोरम प्रकार 'foreach :: [a] -> (a -> a) -> [a]' के रूप में करेंगे, तो आप 'foreach [1..20] show' का मूल्यांकन करने में असमर्थ होंगे, क्योंकि 'शो' एक 'स्ट्रिंग' उत्पन्न करता है, और आपका फ़ंक्शन एक प्रकार का मान लेता है और उसी प्रकार का मान देता है। –

+0

धन्यवाद yasir ;-) –

+0

: -O आपका स्वागत है @Stephane प्रश्न टैग "हैकसेल" "योजना", "रैकेट" या "एरलांग" से कहीं अधिक सक्रिय हैं। मुझे लगता है कि मुझे थोड़ा सा लटका देना है। –

3

प्रकार हस्ताक्षर आप देते हैं, (कम से कम हास्केल संकलक की राय में) जाली। यह एक ऐसा फ़ंक्शन है जो किसी भी a की वस्तुओं और के किसी भी प्रकार f का मान लेता है, और प्रकार r के मानों की एक सूची तैयार करता है। यह कहने जैसा है "मेरे पास हाथी और एक पेंचदार का गुच्छा है। प्रत्येक हाथी को आम में बदल दें"।

ऐसा लगता है अपने लक्ष्य map समारोह को लागू करने के लिए है:

map :: (a -> b) -> [a] -> [b] 
बेशक

, यह तर्क फ्लिप करने पूरी तरह से वैध है:

foreach :: [a] -> (a -> b) -> [b] 

आपका कार्यान्वयन बहुत करीब है, लेकिन वहाँ एक हैं कुछ मुद्दे

सबसे बड़ी बात को ध्यान में रखना है कि आप सूचियों, नहीं सरणियों साथ काम कर रहे है। : ऑपरेटर, जिसे "विपक्ष" भी कहा जाता है, एक आइटम लेता है और उसे एक सूची में प्रस्तुत करता है (उदा। 1 : [2,3,4])। आप वस्तुओं और सूचियों को मनमाने ढंग से संयोजित करने के लिए इसका उपयोग नहीं कर सकते हैं, जैसा कि आप []:(f x) में करते हैं। ++ ऑपरेटर है जो दो सूचियों को जोड़ता है (उदा। [f x] ++ xs, जो (f x) : xs जैसा ही है), लेकिन आपको इसे foreach लागू करने की आवश्यकता नहीं है।

आखिरकार, (foreach (xs f)) ऐसा नहीं करता जो आप सोच सकते हैं। यह सी-स्टाइल भाषा में foreach(xs,f) की तरह नहीं है, यह foreach(xs(f)) जैसा है। (xs f), स्वयं ही, xs को फ़ंक्शन के रूप में उपयोग करने और f को तर्क के रूप में लागू करने जैसा है। इसके बजाय, आप (foreach xs f) चाहते हैं।

मैं बहुत दूर देने से बचने के लिए यहां रुक जाऊंगा। हालांकि एक छोटी सी बात: फ़ंक्शन एप्लिकेशन की किसी भी ऑपरेटर की तुलना में अधिक प्राथमिकता है, इसलिए (f x) : (foreach xs f) के बजाय, आप f x : foreach xs f कह सकते हैं।

+0

के कार्यान्वयन के साथ महान उदाहरण यह जानना अच्छा है कि यह पहले से ही मानचित्र के रूप में मौजूद है। मैंने इसे ट्यूटोरियल में इस्तेमाल किया है लेकिन मैं इसे भूल गया ;-), अब मैं इसका इस्तेमाल करूंगा। मैंने लेक्सह ऑटो-समापन प्रस्ताव के रूप में कीवर्ड फॉरल के अस्तित्व को भी देखा है, लेकिन मुझे इसका वाक्यविन्यास नहीं मिला। –

+0

@ स्टीफन रोलैंड: 'एक बी के लिए। (ए -> बी) -> [ए] -> [बी] '। इस वाक्यविन्यास का उपयोग करने के लिए आपको एक हास्केल भाषा एक्सटेंशन सक्षम करने की आवश्यकता होगी। [मौजूदा रूप से मात्राबद्ध प्रकार] देखें (http://en.wikibooks.org/wiki/Haskell/Existentially_quantified_types)। –