2011-10-02 16 views
5

के लिए मेरे पेड़ सेहास्केल मानचित्र पेड़

data Tree a = Leaf a | Node (Tree a) (Tree a) 
     deriving (Show) 

परिभाषित किया गया है मैं भी एक परीक्षण पेड़ की घोषणा।

myTree = Node (Node (Leaf 1) (Leaf 2)) (Leaf 3) 

मैं जो करना चाहता हूं वह एक समारोह मैपट्री एफ बनाता है जो पत्ता पर कार्य करेगा। अधिक विशेष रूप से होने के लिए, f x = x +1,

तो maptree f myTree वापस आ जाएगी

Node (Node (Leaf 2) (Leaf 3)) (Leaf 4) 

मेरे समाधान

maptree f (Leaf a)= Leaf (f a) 
maptree f (Node xl xr) = Node (maptree xl) (maptree xr) 

है लेकिन यह निम्न त्रुटि

Couldn't match expected type `Tree a' 
     against inferred type `Tree t -> Tree t' 
Probable cause: `maptree' is applied to too few arguments 
In the first argument of `Node', namely `(maptree xl)' 
In the expression: Node (maptree xl) (maptree xr) 

विफल, मॉड्यूल लोड वापस आ जाएगी : कोई नहीं।

हालांकि, यह बाहर काम करता है अगर मैं

maptree (Leaf a)= Leaf (a + 1) 
maptree (Node xl xr) = Node (maptree xl) (maptree xr) 

है।

मैं पहले फ़ंक्शन और दूसरे के बीच का अंतर नहीं देख सकता। मुझे त्रुटि कैसे मिलती है? धन्यवाद।

+1

मुझे अब यह काम मिल गया है। मैं बेवकूफ हूँ ...>< –

+0

maptree f (नोड xl xr) = node (maptree f xl) (maptree f xr) maptree f (नोड xl xr) = नोड (maptree xl) के बजाय होना चाहिए (maptree xr) –

उत्तर

3

एक गूंगा तरह से समारोह पास किया जा सके जैसा कि आप गहरी recurse (उच्च क्रम समारोह की इस तरह के लिए) एक सहायक का उपयोग करने भूल नहीं करने के लिए किया जाता है:

maptree f (Leaf a)  = Leaf (f a) 
maptree f (Node xl xr) = Node (go xl) (go xr) 
    where go = maptree f 

या, वैकल्पिक रूप से (और शायद और अधिक सामान्यतः):

maptree f tree = go tree      -- or eta reduce: maptree f = go 
    where go (Leaf a)  = Leaf (f a) 
      go (Node xl xr) = Node (go xl) (go xr) 

पहले उदाहरण में, मैं maptree f के लिए मैक्रो के रूप में की go प्रकार का उपयोग करें। दूसरे उदाहरण में, मैं इस तथ्य का लाभ उठाता हूं कि maptree का इनपुट fgo फ़ंक्शन के अंदर दायरे में है क्योंकि gowheremaptree के खंड में घोषित किया गया है।

8

आप पुनरावर्ती maptree कॉल पर समारोह याद कर रहे हैं:

maptree f (Leaf a)= Leaf (f a) 
maptree f (Node xl xr) = Node (maptree xl) (maptree xr) 

maptree f (Leaf a)= Leaf (f a) 
maptree f (Node xl xr) = Node (maptree f xl) (maptree f xr) 
5

त्रुटि संदेश मूल रूप से आपको बताता है कि क्या गलत है होना चाहिए: आप maptree पर्याप्त तर्क गुजर नहीं कर रहे हैं। परिभाषा maptree f (Node xl xr) कहती है कि maptree दो तर्क, एक समारोह और एक पेड़ लेता है। लेकिन जब आप इसे maptree xl कहते हैं, तो आप इसे केवल एक तर्क (एक पेड़) दे रहे हैं।

अपने दूसरे संस्करण में, आपने केवल एक तर्क (एक पेड़) लेने के लिए maptree परिभाषित किया है, यही कारण है कि यह उस त्रुटि का उत्पादन नहीं करता है।

उदाहरण के लिए, के बजाय maptree f xl पर कॉल करके आप अपनी समस्या को ठीक कर सकते हैं।

8

ध्यान दें कि यह आपके Tree प्रकार के लिए Functor उदाहरण का स्पष्ट fmap है। इसलिए आप DeriveFunctor एक्सटेंशन का उपयोग कर सकते हैं ताकि जीएचसी आपके लिए उत्पन्न हो सके।

{-# LANGUAGE DeriveFunctor #-} 
data Tree a = Leaf a | Node (Tree a) (Tree a) 
    deriving (Functor, Show) 

आइए इसे आज़माएं।

*Main> fmap (+1) (Node (Node (Leaf 1) (Leaf 2)) (Leaf 3)) 
Node (Node (Leaf 2) (Leaf 3)) (Leaf 4) 
संबंधित मुद्दे