-- Ascundem funcțiile predefinite, pentru a le redefini noi import Prelude hiding (sum, length) --------------------Reduceri liniare data Folder a b c = Folder { foldNull :: c , foldCons :: a -> b -> c } fold :: Foldable t => Folder a b b -> t a -> b fold folder = foldr (foldCons folder) (foldNull folder) sum :: (Foldable t, Num a) => t a -> a sum = fold sumFolder sumFolder :: Num a => Folder a a a sumFolder = Folder { foldNull = 0 , foldCons = (+) } length :: Foldable t => t a -> Int length = fold lenFolder lenFolder :: Folder a Int Int lenFolder = Folder { foldNull = 0 , foldCons = const (+ 1) } --------------------Combinare reduceri --Reduceri independente infixl 5 <+> (<+>) :: Folder a b b -> Folder a c c -> Folder a (b, c) (b, c) f <+> g = Folder { foldNull = (foldNull f, foldNull g) , foldCons = \a (b, c) -> (foldCons f a b, foldCons g a c) } sumLen :: (Foldable t, Num a) => t a -> (a, Int) sumLen = fold (sumFolder <+> lenFolder) --Reduceri semidependente (dreapta depinde de stânga) infixl 5 >.> (>.>) :: Folder a b b -> Folder a (b, c) c -> Folder a (b, c) (b, c) f >.> g = Folder { foldNull = (foldNull f, foldNull g) , foldCons = \a (b, c) -> (foldCons f a b, foldCons g a (b, c)) } -- steep :: (Ord a, Num a) => [a] -> Bool -- steep [] = True -- steep (x : xs) = x > sum xs && steep xs --steep :: (Ord a, Num a) => [a] -> Bool --steep = --steepFolder :: Ord a => Folder a (a, Bool) Bool --Reduceri mutual dependente infixl 5 <.> (<.>) :: Folder a (b, c) b -> Folder a (b, c) c -> Folder a (b, c) (b, c) f <.> g = Folder { foldNull = (foldNull f, foldNull g) , foldCons = \a (b, c) -> (foldCons f a (b, c), foldCons g a (b, c)) } -- evenSum :: Num a => [a] -> a -- evenSum [] = 0 -- evenSum (x : xs) = x + oddSum xs -- oddSum :: Num a => [a] -> a -- oddSum [] = 0 -- oddSum (x : xs) = evenSum xs --evenOddSums :: Num a => [a] -> (a, a) --evenOddSums = --evenFolder :: Num a => Folder a (a, a) a --evenFolder = Folder --oddFolder :: Num a => Folder a (a, a) a --oddFolder = Folder --------------------Reduceri ierarhice data BST a = BSTNil | BSTNod { vl :: a, lt :: BST a, rt :: BST a} data BSTFolder a b c = BSTFolder { foldNil :: c , foldNod :: a -> b -> b -> c } foldBST :: BSTFolder a b b -> BST a -> b foldBST folder = go where go BSTNil = foldNil folder go (BSTNod elem left right) = foldNod folder elem (go left) (go right) --height :: BST a -> Int --height = foldBST heightFolder -- height $ BSTNod 1 BSTNil (BSTNod 2 BSTNil (BSTNod 5 (BSTNod 4 BSTNil BSTNil) BSTNil)) --heightFolder :: BSTFolder a Int Int --heightFolder = BSTFolder