इस एन्कोडिंग का एक अच्छा तरीका Data.Foldable द्वारा प्रदान की ट्रेवर्सल पर दुबला करने के लिए है।
{-# LANGUAGE DeriveFunctor, DeriveFoldable #-}
import Data.Foldable
import Data.Monoid
हम इसे का एक उदाहरण स्वचालित रूप से एक एक्सटेंशन का उपयोग प्राप्त कर सकते हैं, लेकिन हम नोड निर्माता के क्षेत्र को पुन: व्यवस्थित करने के लिए हमें एक में आदेश ट्रावर्सल प्रदान करने के लिए की जरूरत है।
हम उस पर होते हैं, तो हम डेटा प्रकार पर ही बाधाओं को खत्म करना चाहिए। वे वास्तव में कोई लाभ नहीं प्रदान करते हैं और हास्केल 2011 के रूप में भाषा से हटा दिया गया (आप इस तरह की कमी का उपयोग करना चाहते जब आप, वर्गों के उदाहरण पर डाल चाहिए डेटा प्रकार पर नहीं।)
data BST a
= Void
| Node
{ left :: BST a
, val :: a
, right :: BST a
} deriving (Eq, Ord, Read, Show, Foldable)
पहले हम परिभाषित इसका क्या मतलब एक के लिए सूची सख्ती से क्रमबद्ध करना।
sorted :: Ord a => [a] -> Bool
sorted [] = True
sorted [x] = True
sorted (x:xs) = x < head xs && sorted xs
-- head is safe because of the preceeding match.
फिर हम उपयोग कर सकते हैं toListविधि द्वारा प्रदान की Data.Foldableऔर इसके बाद के संस्करण सहायक।
isBST :: Ord a => BST a -> Bool
isBST = sorted . toList
हम भी इस अधिक सीधे लागू कर सकते हैं, जैसे आप से पूछा। जब से हम डेटा प्रकार पर नकली बाधाओं को हटा दिया है, हम अपने गुना की परिभाषा को आसान बनाने में कर सकते हैं।
cata :: (b -> a -> b -> b) -> b -> BST a -> b
cata _ z Void = z
cata f z (Node l x r) = f (cata f z l) x (cata f z r)
अब हम हमारी catamorphism है, जो यह है कि हम या तो कोई नोड्स (राशि का परिणाम मॉडल करने के लिए डेटा प्रकार की जरूरत है Z), या सख्ती से बढ़ रही है नोड्स की एक सीमा ( T) या विफल रहे हैं ( X)
data T a = Z | T a a | X deriving Eq
और हम तो लागू कर सकते हैं isBSTसीधे
isBST' :: Ord a => BST a -> Bool
isBST' b = cata phi Z b /= X where
phi X _ _ = X
phi _ _ X = X
phi Z a Z = T a a
phi Z a (T b c) = if a < b then T a c else X
phi (T a b) c Z = if b < c then T a c else X
phi (T a b) c (T d e) = if b < c && c < d then T a e else X
इसमें कुछ समय कठिन है, इसलिए शायद यह बेहतर होगा जिस तरह से हम अंतरिम राज्यों थोड़ा रचना विघटित करने के लिए:
cons :: Ord a => a -> T a -> T a
cons _ X = X
cons a Z = T a a
cons a (T b c) = if a < b then T a c else X
instance Ord a => Monoid (T a) where
mempty = Z
Z `mappend` a = a
a `mappend` Z = a
X `mappend` _ = X
_ `mappend` X = X
T a b `mappend` T c d = if b < c then T a d else X
isBST'' :: Ord a => BST a -> Bool
isBST'' b = cata phi Z b /= X where
phi l a r = l `mappend` cons a r
व्यक्तिगत रूप से, मैं शायद सिर्फ Foldable उदाहरण का उपयोग करेंगे।