packages feed

rose-trees 0.0.1.1 → 0.0.2

raw patch · 13 files changed

+752/−60 lines, 13 filesdep +criteriondep +mtldep +rose-treesdep −data-defaultdep −hspecdep −pseudo-triedep ~basesetup-changedPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: criterion, mtl, rose-trees, semigroupoids, sets, tasty, tasty-quickcheck, witherable

Dependencies removed: data-default, hspec, pseudo-trie, transformers

Dependency ranges changed: base

API changes (from Hackage documentation)

- Data.Tree.Knuth: Fork :: a -> (KnuthForest a) -> (KnuthForest a) -> KnuthForest a
- Data.Tree.Knuth: Nil :: KnuthForest a
- Data.Tree.Knuth: appendSibling :: KnuthForest a -> KnuthForest a -> KnuthForest a
- Data.Tree.Knuth: children :: KnuthForest a -> (KnuthForest a)
- Data.Tree.Knuth: data KnuthForest a
- Data.Tree.Knuth: instance Eq a => Eq (KnuthForest a)
- Data.Tree.Knuth: instance Eq a => Eq (KnuthTree a)
- Data.Tree.Knuth: instance Foldable KnuthForest
- Data.Tree.Knuth: instance Foldable KnuthTree
- Data.Tree.Knuth: instance Functor KnuthForest
- Data.Tree.Knuth: instance Functor KnuthTree
- Data.Tree.Knuth: instance Monoid (KnuthForest a)
- Data.Tree.Knuth: instance Show a => Show (KnuthForest a)
- Data.Tree.Knuth: instance Show a => Show (KnuthTree a)
- Data.Tree.Knuth: node :: KnuthForest a -> a
- Data.Tree.Knuth: siblings :: KnuthForest a -> (KnuthForest a)
- Data.Tree.Knuth: unKnuthTree :: KnuthTree a -> (a, KnuthForest a)
- Data.Tree.Rose: PT :: (t, Maybe a) -> PT t a
- Data.Tree.Rose: instance Default t => RoseTree (PseudoTrie t) NonEmpty (PT t)
- Data.Tree.Rose: instance RoseTree KnuthForest Identity Identity
- Data.Tree.Rose: instance RoseTree Tree [] Identity
- Data.Tree.Rose: newtype PT t a
+ Data.Tree.Knuth: [unKnuthTree] :: KnuthTree a -> (a, KnuthForest a)
+ Data.Tree.Knuth: delete :: Eq a => a -> KnuthTree a -> Maybe (KnuthTree a)
+ Data.Tree.Knuth: difference :: Eq a => KnuthTree a -> KnuthTree a -> Maybe (KnuthTree a)
+ Data.Tree.Knuth: elem :: Eq a => a -> KnuthTree a -> Bool
+ Data.Tree.Knuth: firstTree :: KnuthForest a -> Maybe (KnuthTree a)
+ Data.Tree.Knuth: instance Data.Foldable.Foldable Data.Tree.Knuth.KnuthTree
+ Data.Tree.Knuth: instance Data.Semigroup.Semigroup (Data.Tree.Knuth.KnuthTree a)
+ Data.Tree.Knuth: instance Data.Set.Class.HasSingleton a (Data.Tree.Knuth.KnuthTree a)
+ Data.Tree.Knuth: instance Data.Set.Class.HasSize (Data.Tree.Knuth.KnuthTree a)
+ Data.Tree.Knuth: instance Data.Set.Class.HasUnion (Data.Tree.Knuth.KnuthTree a)
+ Data.Tree.Knuth: instance Data.Traversable.Traversable Data.Tree.Knuth.KnuthTree
+ Data.Tree.Knuth: instance GHC.Base.Applicative Data.Tree.Knuth.KnuthTree
+ Data.Tree.Knuth: instance GHC.Base.Functor Data.Tree.Knuth.KnuthTree
+ Data.Tree.Knuth: instance GHC.Base.Monad Data.Tree.Knuth.KnuthTree
+ Data.Tree.Knuth: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Tree.Knuth.KnuthTree a)
+ Data.Tree.Knuth: instance GHC.Show.Show a => GHC.Show.Show (Data.Tree.Knuth.KnuthTree a)
+ Data.Tree.Knuth: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Data.Tree.Knuth.KnuthTree a)
+ Data.Tree.Knuth: intersection :: Eq a => KnuthTree a -> KnuthTree a -> Maybe (KnuthTree a)
+ Data.Tree.Knuth: isChildOf :: Eq a => a -> KnuthTree a -> Bool
+ Data.Tree.Knuth: isDescendantOf :: Eq a => a -> KnuthTree a -> Bool
+ Data.Tree.Knuth: isProperDescendantOf :: Eq a => a -> KnuthTree a -> Bool
+ Data.Tree.Knuth: isProperSubtreeOf :: Eq a => KnuthTree a -> KnuthTree a -> Bool
+ Data.Tree.Knuth: isProperSubtreeOf' :: Eq a => KnuthTree a -> KnuthTree a -> Bool
+ Data.Tree.Knuth: isSubtreeOf :: Eq a => KnuthTree a -> KnuthTree a -> Bool
+ Data.Tree.Knuth: isSubtreeOf' :: Eq a => KnuthTree a -> KnuthTree a -> Bool
+ Data.Tree.Knuth: singleton :: a -> KnuthTree a
+ Data.Tree.Knuth: size :: KnuthTree a -> Int
+ Data.Tree.Knuth: union :: KnuthTree a -> KnuthTree a -> KnuthTree a
+ Data.Tree.Knuth.Forest: Fork :: a -> KnuthForest a -> KnuthForest a -> KnuthForest a
+ Data.Tree.Knuth.Forest: Nil :: KnuthForest a
+ Data.Tree.Knuth.Forest: [kChildren] :: KnuthForest a -> KnuthForest a
+ Data.Tree.Knuth.Forest: [kNode] :: KnuthForest a -> a
+ Data.Tree.Knuth.Forest: [kSiblings] :: KnuthForest a -> KnuthForest a
+ Data.Tree.Knuth.Forest: data KnuthForest a
+ Data.Tree.Knuth.Forest: delete :: Eq a => a -> KnuthForest a -> KnuthForest a
+ Data.Tree.Knuth.Forest: difference :: Eq a => KnuthForest a -> KnuthForest a -> KnuthForest a
+ Data.Tree.Knuth.Forest: elem :: Eq a => a -> KnuthForest a -> Bool
+ Data.Tree.Knuth.Forest: instance Data.Foldable.Foldable Data.Tree.Knuth.Forest.KnuthForest
+ Data.Tree.Knuth.Forest: instance Data.Semigroup.Semigroup (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance Data.Set.Class.HasEmpty (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance Data.Set.Class.HasSingleton a (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance Data.Set.Class.HasSize (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance Data.Set.Class.HasUnion (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance Data.Traversable.Traversable Data.Tree.Knuth.Forest.KnuthForest
+ Data.Tree.Knuth.Forest: instance Data.Witherable.Witherable Data.Tree.Knuth.Forest.KnuthForest
+ Data.Tree.Knuth.Forest: instance GHC.Base.Alternative Data.Tree.Knuth.Forest.KnuthForest
+ Data.Tree.Knuth.Forest: instance GHC.Base.Applicative Data.Tree.Knuth.Forest.KnuthForest
+ Data.Tree.Knuth.Forest: instance GHC.Base.Functor Data.Tree.Knuth.Forest.KnuthForest
+ Data.Tree.Knuth.Forest: instance GHC.Base.Monad Data.Tree.Knuth.Forest.KnuthForest
+ Data.Tree.Knuth.Forest: instance GHC.Base.MonadPlus Data.Tree.Knuth.Forest.KnuthForest
+ Data.Tree.Knuth.Forest: instance GHC.Base.Monoid (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance GHC.Classes.Eq a => Data.Set.Class.HasDelete a (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance GHC.Classes.Eq a => Data.Set.Class.HasDifference (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance GHC.Classes.Eq a => Data.Set.Class.HasIntersection (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance GHC.Show.Show a => GHC.Show.Show (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Data.Tree.Knuth.Forest.KnuthForest a)
+ Data.Tree.Knuth.Forest: intersection :: Eq a => KnuthForest a -> KnuthForest a -> KnuthForest a
+ Data.Tree.Knuth.Forest: isChildOf :: Eq a => a -> KnuthForest a -> Bool
+ Data.Tree.Knuth.Forest: isDescendantOf :: Eq a => a -> KnuthForest a -> Bool
+ Data.Tree.Knuth.Forest: isProperDescendantOf :: Eq a => a -> KnuthForest a -> Bool
+ Data.Tree.Knuth.Forest: isProperSubforestOf :: Eq a => KnuthForest a -> KnuthForest a -> Bool
+ Data.Tree.Knuth.Forest: isProperSubforestOf' :: Eq a => KnuthForest a -> KnuthForest a -> Bool
+ Data.Tree.Knuth.Forest: isSiblingOf :: Eq a => a -> KnuthForest a -> Bool
+ Data.Tree.Knuth.Forest: isSubforestOf :: Eq a => KnuthForest a -> KnuthForest a -> Bool
+ Data.Tree.Knuth.Forest: isSubforestOf' :: Eq a => KnuthForest a -> KnuthForest a -> Bool
+ Data.Tree.Knuth.Forest: singleton :: a -> KnuthForest a
+ Data.Tree.Knuth.Forest: size :: KnuthForest a -> Int
+ Data.Tree.Knuth.Forest: union :: KnuthForest a -> KnuthForest a -> KnuthForest a
+ Data.Tree.Rose: instance Data.Tree.Rose.RoseTree Data.Tree.Knuth.Forest.KnuthForest
+ Data.Tree.Rose: instance Data.Tree.Rose.RoseTree Data.Tree.Knuth.KnuthTree
+ Data.Tree.Rose: instance Data.Tree.Rose.RoseTree Data.Tree.Set.SetTree
+ Data.Tree.Rose: instance Data.Tree.Rose.RoseTree Data.Tree.Tree
+ Data.Tree.Set: SetTree :: a -> Set (SetTree a) -> SetTree a
+ Data.Tree.Set: [sChildren] :: SetTree a -> Set (SetTree a)
+ Data.Tree.Set: [sNode] :: SetTree a -> a
+ Data.Tree.Set: data SetTree a
+ Data.Tree.Set: delete :: Eq a => a -> SetTree a -> Maybe (SetTree a)
+ Data.Tree.Set: elem :: Eq a => a -> SetTree a -> Bool
+ Data.Tree.Set: eqHead :: Eq a => SetTree a -> SetTree a -> Bool
+ Data.Tree.Set: filter :: Eq a => (a -> Bool) -> SetTree a -> Maybe (SetTree a)
+ Data.Tree.Set: insertChild :: Ord a => SetTree a -> SetTree a -> SetTree a
+ Data.Tree.Set: instance (GHC.Classes.Ord a, Test.QuickCheck.Arbitrary.Arbitrary a) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Tree.Set.SetTree a)
+ Data.Tree.Set: instance Data.Foldable.Foldable Data.Tree.Set.SetTree
+ Data.Tree.Set: instance Data.Semigroup.Foldable.Class.Foldable1 Data.Tree.Set.SetTree
+ Data.Tree.Set: instance Data.Set.Class.HasSingleton a (Data.Tree.Set.SetTree a)
+ Data.Tree.Set: instance Data.Set.Class.HasSize (Data.Tree.Set.SetTree a)
+ Data.Tree.Set: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Tree.Set.SetTree a)
+ Data.Tree.Set: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Tree.Set.SetTree a)
+ Data.Tree.Set: instance GHC.Show.Show a => GHC.Show.Show (Data.Tree.Set.SetTree a)
+ Data.Tree.Set: isChildOf :: Eq a => a -> SetTree a -> Bool
+ Data.Tree.Set: isDescendantOf :: Eq a => a -> SetTree a -> Bool
+ Data.Tree.Set: isProperSubtreeOf :: Eq a => SetTree a -> SetTree a -> Bool
+ Data.Tree.Set: isProperSubtreeOf' :: Eq a => SetTree a -> SetTree a -> Bool
+ Data.Tree.Set: isSubtreeOf :: Eq a => SetTree a -> SetTree a -> Bool
+ Data.Tree.Set: isSubtreeOf' :: Eq a => SetTree a -> SetTree a -> Bool
+ Data.Tree.Set: map :: Ord b => (a -> b) -> SetTree a -> SetTree b
+ Data.Tree.Set: mapMaybe :: Eq b => (a -> Maybe b) -> SetTree a -> Maybe (SetTree b)
+ Data.Tree.Set: singleton :: a -> SetTree a
+ Data.Tree.Set: size :: SetTree a -> Int
- Data.Tree.Rose: (@->) :: RoseTree c u t => t a -> u (c a) -> c a
+ Data.Tree.Rose: (@->) :: RoseTree c => Head (c a) -> Tail (c a) -> c a
- Data.Tree.Rose: class RoseTree (c :: * -> *) (u :: * -> *) (t :: * -> *) | c -> u, c -> t
+ Data.Tree.Rose: class RoseTree (c :: * -> *)

Files

− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
+ bench/Bench.hs view
@@ -0,0 +1,18 @@+module Main where++import qualified Data.Tree+import           Data.TreeBench+import           Data.Tree.SetBench+import           Data.Tree.KnuthBench+import           Criterion.Main+++++main = defaultMain+  [ bgroup "Trees"+    [ data_tree_bench+    , data_settree_bench+    , data_knuthtree_bench+    ]+  ]
+ bench/Data/Tree/KnuthBench.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE+    FlexibleContexts+  #-}++module Data.Tree.KnuthBench (data_knuthtree_bench) where++import Prelude hiding (elem)+import Data.Monoid+import Data.Tree.Knuth+import qualified Data.Tree.Knuth.Forest as F+import Control.Monad.State+import Criterion+++newNode :: MonadState Int m => F.KnuthForest Int -> m (KnuthTree Int)+newNode xs = do x <- get+                modify (+1)+                return $ KnuthTree (x, xs)++-- makeWith :: Int -> Int -> Int -> State Int (Tree Int)+makeWith d w r | d <= 1 || w <= 1 = return F.Nil+               | otherwise = do ws <- makeWith d (w-1) r+                                xs <- makeWith (d-1) (floor $ fromIntegral w / r) r+                                x <- get+                                modify (+1)+                                return $ F.Fork x xs ws++tree1 = evalState (makeWith 1 1 2 >>= newNode) 1+tree2 = evalState (makeWith 2 2 2 >>= newNode) 1+tree3 = evalState (makeWith 3 3 2 >>= newNode) 1+tree4 = evalState (makeWith 4 4 2 >>= newNode) 1+tree5 = evalState (makeWith 5 5 2 >>= newNode) 1+++data_knuthtree_bench = bgroup "Data.Tree.Knuth"+  [ bgroup "depth"+    [ bench "1" $ whnf (elem 1) tree1+    , bench "2" $ whnf (elem 2) tree2+    , bench "3" $ whnf (elem 5) tree3+    , bench "4" $ whnf (elem 18) tree4+    , bench "5" $ whnf (elem 23) tree5+    ]+  , bgroup "width"+    [ bench "1" $ whnf (elem 1) tree1+    , bench "2" $ whnf (elem 2) tree2+    , bench "3" $ whnf (elem 6) tree3+    , bench "4" $ whnf (elem 20) tree4+    , bench "5" $ whnf (elem 25) tree5+    ]+  ]
+ bench/Data/Tree/SetBench.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE+    FlexibleContexts+  #-}++module Data.Tree.SetBench (data_settree_bench) where++import Prelude hiding (elem)+import Data.Monoid+import qualified Data.Set as Set+import Data.Tree.Set+import Control.Monad.State+import Criterion+++newNode :: MonadState Int m => Set.Set (SetTree Int) -> m (SetTree Int)+newNode xs = do x <- get+                modify (+1)+                return $ SetTree x xs++-- makeWith :: Int -> Int -> Int -> State Int (Tree Int)+makeWith d w r | d <= 1 = newNode Set.empty+               | otherwise = do xs <- replicateM w $ makeWith (d-1) (floor $ fromIntegral w / r) r+                                newNode $ Set.fromList xs++tree1 = evalState (makeWith 1 1 2) 1+tree2 = evalState (makeWith 2 2 2) 1+tree3 = evalState (makeWith 3 3 2) 1+tree4 = evalState (makeWith 4 4 2) 1+tree5 = evalState (makeWith 5 5 2) 1+++data_settree_bench = bgroup "Data.Tree.Set"+  [ bgroup "depth"+    [ bench "1" $ whnf (elem 1) tree1+    , bench "2" $ whnf (elem 2) tree2+    , bench "3" $ whnf (elem 5) tree3+    , bench "4" $ whnf (elem 18) tree4+    , bench "5" $ whnf (elem 23) tree5+    ]+  , bgroup "width"+    [ bench "1" $ whnf (elem 1) tree1+    , bench "2" $ whnf (elem 2) tree2+    , bench "3" $ whnf (elem 6) tree3+    , bench "4" $ whnf (elem 20) tree4+    , bench "5" $ whnf (elem 25) tree5+    ]+  ]
+ bench/Data/TreeBench.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE+    FlexibleContexts+  #-}++module Data.TreeBench (data_tree_bench) where++import Data.Monoid+import Data.Tree+import Data.Tree.Rose+import Control.Monad.State+import Criterion+++newNode :: MonadState Int m => [Tree Int] -> m (Tree Int)+newNode xs = do x <- get+                modify (+1)+                return $ Node x xs++-- makeWith :: Int -> Int -> Int -> State Int (Tree Int)+makeWith d w r | d <= 1 = newNode []+               | otherwise = do xs <- replicateM w $ makeWith (d-1) (floor $ (fromIntegral w) / r) r+                                newNode xs++tree1 = evalState (makeWith 1 1 2) 1+tree2 = evalState (makeWith 2 2 2) 1+tree3 = evalState (makeWith 3 3 2) 1+tree4 = evalState (makeWith 4 4 2) 1+tree5 = evalState (makeWith 5 5 2) 1+++data_tree_bench = bgroup "Data.Tree"+  [ bgroup "depth"+    [ bench "1" $ whnf (elemT 1) tree1+    , bench "2" $ whnf (elemT 2) tree2+    , bench "3" $ whnf (elemT 5) tree3+    , bench "4" $ whnf (elemT 18) tree4+    , bench "5" $ whnf (elemT 23) tree5+    ]+  , bgroup "width"+    [ bench "1" $ whnf (elemT 1) tree1+    , bench "2" $ whnf (elemT 2) tree2+    , bench "3" $ whnf (elemT 6) tree3+    , bench "4" $ whnf (elemT 20) tree4+    , bench "5" $ whnf (elemT 25) tree5+    ]+  ]++elemT :: Eq a => a -> Tree a -> Bool+elemT x (Node y ys) = x == y || getAny (foldMap (Any . elemT x) ys)
rose-trees.cabal view
@@ -1,5 +1,5 @@ Name:                   rose-trees-Version:                0.0.1.1+Version:                0.0.2 Author:                 Athan Clark <athan.clark@gmail.com> Maintainer:             Athan Clark <athan.clark@gmail.com> License:                BSD3@@ -8,6 +8,7 @@ -- Description: Cabal-Version:          >= 1.10 Build-Type:             Simple+Category:               Data, Tree  Library   Default-Language:     Haskell2010@@ -15,13 +16,18 @@   GHC-Options:          -Wall   Exposed-Modules:      Data.Tree.Rose                         Data.Tree.Knuth-  Other-Modules:        Data.Tree.Rose.Internal-  Build-Depends:        base >= 4 && < 5+                        Data.Tree.Knuth.Forest+                        Data.Tree.Set+  Build-Depends:        base >= 4.6 && < 5                       , containers                       , semigroups-                      , data-default-                      , pseudo-trie-                      , transformers+                      , semigroupoids+                      , witherable+                      , sets+                      , QuickCheck+                      , quickcheck-instances+                      , mtl+                      , criterion  Test-Suite spec   Type:                 exitcode-stdio-1.0@@ -30,10 +36,48 @@                       , test   Ghc-Options:          -Wall   Main-Is:              Spec.hs+  Other-Modules:        Data.Tree.Knuth+                        Data.Tree.Knuth.Forest+                        Data.Tree.Rose+                        Data.Tree.Set+                        Data.Tree.RoseSpec   Build-Depends:        base-                      , hspec+                      , rose-trees+                      , witherable+                      , containers+                      , semigroups+                      , semigroupoids+                      , sets+                      , tasty+                      , tasty-quickcheck                       , QuickCheck                       , quickcheck-instances++Benchmark bench+  Type:                 exitcode-stdio-1.0+  Default-Language:     Haskell2010+  Hs-Source-Dirs:       src+                      , bench+  Ghc-Options:          -Wall+  Main-Is:              Bench.hs+  Other-Modules:        Data.Tree.Knuth+                        Data.Tree.Knuth.Forest+                        Data.Tree.Rose+                        Data.Tree.Set+                        Data.TreeBench+                        Data.Tree.SetBench+                        Data.Tree.KnuthBench+  Build-Depends:        base+                      , rose-trees+                      , witherable+                      , containers+                      , semigroups+                      , semigroupoids+                      , sets+                      , QuickCheck+                      , quickcheck-instances+                      , mtl+                      , criterion  Source-Repository head   Type:                 git
src/Data/Tree/Knuth.hs view
@@ -1,36 +1,140 @@-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE+    DeriveFunctor+  , DeriveFoldable+  , DeriveTraversable+  , GeneralizedNewtypeDeriving+  , MultiParamTypeClasses+  , FlexibleInstances+  #-} +-- |+-- Module      : Data.Tree.Knuth+-- Copyright   : (c) 2014, 2015 Athan Clark+--+-- License     : BSD-style+-- Maintainer  : athan.clark@gmail.com+-- Stability   : experimental+-- Portability : GHC+--+-- An implementation of+-- <https://en.wikipedia.org/wiki/Left-child_right-sibling_binary_tree left-child, right-sibling binary trees>.+ module Data.Tree.Knuth where -import Prelude hiding (foldr)-import Data.Monoid-import Data.Foldable+import qualified Data.Tree.Knuth.Forest as KF -data KnuthForest a = Fork { node :: a-                          , children :: (KnuthForest a)-                          , siblings :: (KnuthForest a) }-                   | Nil-  deriving (Show, Eq, Functor)+import Data.Semigroup+import Data.Foldable as F+import Data.Maybe+import qualified Data.Set.Class as Sets+import Control.Applicative+import Control.Monad -appendSibling :: KnuthForest a -> KnuthForest a -> KnuthForest a-appendSibling Nil _ = Nil-appendSibling (Fork x xc Nil) y = Fork x xc y-appendSibling (Fork x xc xs) y = Fork x xc $ appendSibling xs y+import Test.QuickCheck -instance Monoid (KnuthForest a) where-  mempty = Nil-  mappend = appendSibling -instance Foldable KnuthForest where-  foldr f acc Nil = acc-  foldr f acc (Fork x xc xs) =-    foldr f (foldr f (f x acc) xs) xc+newtype KnuthTree a = KnuthTree { unKnuthTree :: (a, KF.KnuthForest a) }+  deriving (Show, Eq, Functor, Foldable, Traversable) -newtype KnuthTree a = KnuthTree { unKnuthTree :: (a, KnuthForest a) }-  deriving (Show, Eq, Functor)+instance Arbitrary a => Arbitrary (KnuthTree a) where+  arbitrary = do+    x <- arbitrary+    xs <- arbitrary+    return $ KnuthTree (x,xs) --- | Breadth-first-instance Foldable KnuthTree where-  foldr f acc (KnuthTree (x, xs)) = foldr f (f x acc) xs+firstTree :: KF.KnuthForest a -> Maybe (KnuthTree a)+firstTree KF.Nil = Nothing+firstTree (KF.Fork x xc _) = Just $ KnuthTree (x,xc)+++instance Applicative KnuthTree where+  pure x = KnuthTree (x,KF.Nil)+  (KnuthTree (f,fs)) <*> (KnuthTree (x,xs)) = KnuthTree (f x,fs <*> xs)++instance Monad KnuthTree where+  return x = KnuthTree (x,KF.Nil)+  (KnuthTree (x,xs)) >>= f =+    let (KnuthTree (y,_)) = f x+    in KnuthTree (y,xs >>= (snd . unKnuthTree . f))++instance Semigroup (KnuthTree a) where+  (<>) = union++instance Sets.HasSize (KnuthTree a) where+  size = size++instance Sets.HasSingleton a (KnuthTree a) where+  singleton = singleton++instance Sets.HasUnion (KnuthTree a) where+  union = union++-- ** Query+size :: KnuthTree a -> Int+size (KnuthTree (_,xs)) = 1 + KF.size xs++elem :: Eq a => a -> KnuthTree a -> Bool+elem x (KnuthTree (y,ys)) = x == y || KF.elem x ys++isSubtreeOf :: Eq a => KnuthTree a -> KnuthTree a -> Bool+isSubtreeOf xss yss@(KnuthTree (_,ys)) = xss == yss || go ys+  where+    go KF.Nil = False+    go zss@(KF.Fork x xc xs) = xss == fromJust (firstTree zss) || go xs || go xc++-- | Bottom-up depth-first+isSubtreeOf' :: Eq a => KnuthTree a -> KnuthTree a -> Bool+isSubtreeOf' xss yss@(KnuthTree (_,ys)) = go ys || xss == yss+  where+    go KF.Nil = False+    go zss@(KF.Fork x xc xs) = go xc || go xs || xss == fromJust (firstTree zss)++isProperSubtreeOf :: Eq a => KnuthTree a -> KnuthTree a -> Bool+isProperSubtreeOf xss (KnuthTree (_,ys)) = go ys+  where+    go KF.Nil = False+    go zss@(KF.Fork x xc xs) = xss == fromJust (firstTree zss) || go xs || go xc++-- | Bottom-up depth-first+isProperSubtreeOf' :: Eq a => KnuthTree a -> KnuthTree a -> Bool+isProperSubtreeOf' xss (KnuthTree (_,ys)) = go ys+  where+    go KF.Nil = False+    go zss@(KF.Fork x xc xs) = go xc || go xs || xss == fromJust (firstTree zss)++isChildOf :: Eq a => a -> KnuthTree a -> Bool+isChildOf x (KnuthTree (_,ys)) = KF.isChildOf x ys++isDescendantOf :: Eq a => a -> KnuthTree a -> Bool+isDescendantOf x (KnuthTree (y,ys)) = x == y || KF.isDescendantOf x ys++isProperDescendantOf :: Eq a => a -> KnuthTree a -> Bool+isProperDescendantOf x (KnuthTree (_,ys)) = KF.isDescendantOf x ys++-- ** Construction++singleton :: a -> KnuthTree a+singleton x = KnuthTree (x,KF.Nil)++delete :: Eq a => a -> KnuthTree a -> Maybe (KnuthTree a)+delete x (KnuthTree (y,ys)) | x == y = Nothing+                            | otherwise = Just $ KnuthTree (y, KF.delete x ys)++-- ** Combination++union :: KnuthTree a -> KnuthTree a -> KnuthTree a+union (KnuthTree (_,xs)) (KnuthTree (y,ys)) = KnuthTree (y, KF.union xs ys)++intersection :: Eq a => KnuthTree a -> KnuthTree a -> Maybe (KnuthTree a)+intersection (KnuthTree (x,xs)) (KnuthTree (y,ys)) = do+  guard $ x == y+  return $ KnuthTree (y,KF.intersection xs ys)++difference :: Eq a => KnuthTree a -> KnuthTree a -> Maybe (KnuthTree a)+difference xss@(KnuthTree (x,xs)) (KnuthTree (y,ys)) = do+  guard $ x /= y+  return $ KnuthTree (x,go ys)+  where+    go KF.Nil = KF.Nil+    go zss@(KF.Fork x xc xs) | xss == fromJust (firstTree zss) = KF.Nil+                             | otherwise = KF.Fork x (go xc) (go xs)
+ src/Data/Tree/Knuth/Forest.hs view
@@ -0,0 +1,196 @@+{-# LANGUAGE+    DeriveFunctor+  , MultiParamTypeClasses+  , FlexibleInstances+  #-}++module Data.Tree.Knuth.Forest where++import Prelude hiding (foldr, elem)+import Data.Monoid hiding ((<>))+import Data.Semigroup+import Data.Foldable hiding (elem)+import Data.Witherable+import Data.Traversable+import qualified Data.Set.Class as Sets+import Control.Applicative+import Control.Monad++import Test.QuickCheck+++-- * Forest++data KnuthForest a = Fork { kNode :: a+                          , kChildren :: KnuthForest a+                          , kSiblings :: KnuthForest a }+                   | Nil+  deriving (Show, Eq, Functor)++instance Arbitrary a => Arbitrary (KnuthForest a) where+  arbitrary = oneof [ return Nil+                    , liftA3 Fork arbitrary arbitrary arbitrary+                    ]+++-- | Siblings before children+instance Ord a => Ord (KnuthForest a) where+  compare (Fork x xc xs) (Fork y yc ys) =+    compare x y <> compare xs ys <> compare xc yc+  compare Nil Nil = EQ+  compare Nil _ = LT+  compare _ Nil = GT++-- | Zippy+instance Applicative KnuthForest where+  pure x = Fork x Nil Nil+  Nil <*> _ = Nil+  _ <*> Nil = Nil+  (Fork f fc fs) <*> (Fork x xc xs) =+    Fork (f x) (fc <*> xc) (fs <*> xs)++instance Alternative KnuthForest where+  empty = Nil+  (<|>) = union++-- | Breadth-first+instance Monad KnuthForest where+  return x = Fork x Nil Nil+  Nil >>= _ = Nil+  (Fork x xc xs) >>= f = f x `union` (xs >>= f) `union` (xc >>= f)++instance MonadPlus KnuthForest where+  mzero = Nil+  mplus = union++instance Semigroup (KnuthForest a) where+  (<>) = union++instance Monoid (KnuthForest a) where+  mempty = Nil+  mappend = union++-- | Breadth-first+instance Foldable KnuthForest where+  foldr _ acc Nil = acc+  foldr f acc (Fork x xc xs) =+    foldr f (foldr f (f x acc) xs) xc++instance Traversable KnuthForest where+  sequenceA Nil = pure Nil+  sequenceA (Fork x xc xs) = liftA3 Fork x (sequenceA xc) (sequenceA xs)++instance Witherable KnuthForest where+  catMaybes Nil = Nil+  catMaybes (Fork mx xc xs) = case mx of+    Nothing -> Nil+    Just x -> Fork x (catMaybes xc) (catMaybes xs)++instance Sets.HasUnion (KnuthForest a) where+  union = union++instance Eq a => Sets.HasIntersection (KnuthForest a) where+  intersection = intersection++instance Eq a => Sets.HasDifference (KnuthForest a) where+  difference = difference++instance Sets.HasSize (KnuthForest a) where+  size = size++instance Sets.HasEmpty (KnuthForest a) where+  empty = Nil++instance Sets.HasSingleton a (KnuthForest a) where+  singleton = singleton++instance Eq a => Sets.HasDelete a (KnuthForest a) where+  delete = delete++-- ** Query++size :: KnuthForest a -> Int+size Nil = 0+size (Fork _ xc xs) = 1 + size xc + size xs++-- Breadth-first+elem :: Eq a => a -> KnuthForest a -> Bool+elem _ Nil = False+elem x (Fork y yc ys) = x == y || elem x ys || elem x yc++-- Top-down, breadth-first+isSubforestOf :: Eq a => KnuthForest a -> KnuthForest a -> Bool+isSubforestOf Nil _ = True+isSubforestOf xss yss@(Fork _ yc ys) =+  xss == yss || isSubforestOf xss ys || isSubforestOf xss yc+isSubforestOf _ Nil = False++-- Bottom-up, depth-first+isSubforestOf' :: Eq a => KnuthForest a -> KnuthForest a -> Bool+isSubforestOf' Nil _ = True+isSubforestOf' xss yss@(Fork _ yc ys) =+  isSubforestOf xss yc || isSubforestOf xss ys || xss == yss+isSubforestOf' _ Nil = False++-- | No siblings+isProperSubforestOf :: Eq a => KnuthForest a -> KnuthForest a -> Bool+isProperSubforestOf Nil _ = True+isProperSubforestOf xss (Fork _ yc _) = isSubforestOf xss yc+isProperSubforestOf _ Nil = False++-- | Depth-first+isProperSubforestOf' :: Eq a => KnuthForest a -> KnuthForest a -> Bool+isProperSubforestOf' Nil _ = True+isProperSubforestOf' xss (Fork _ yc _) = isSubforestOf' xss yc+isProperSubforestOf' _ Nil = False++isSiblingOf :: Eq a => a -> KnuthForest a -> Bool+isSiblingOf _ Nil = False+isSiblingOf x (Fork y _ ys) = x == y || isSiblingOf x ys++-- | depth of one+isChildOf :: Eq a => a -> KnuthForest a -> Bool+isChildOf _ Nil = False+isChildOf x (Fork _ yc ys) = isSiblingOf x yc || isChildOf x ys+++isDescendantOf :: Eq a => a -> KnuthForest a -> Bool+isDescendantOf _ Nil = False+isDescendantOf x (Fork y yc _) = x == y || isDescendantOf x yc++isProperDescendantOf :: Eq a => a -> KnuthForest a -> Bool+isProperDescendantOf _ Nil = False+isProperDescendantOf x (Fork _ yc _) = isDescendantOf x yc+++-- ** Construction++singleton :: a -> KnuthForest a+singleton x = Fork x Nil Nil++delete :: Eq a => a -> KnuthForest a -> KnuthForest a+delete _ Nil = Nil+delete x (Fork y yc ys) | x == y = Nil+                        | otherwise = Fork y (delete x yc) (delete x ys)++-- ** Combination++union :: KnuthForest a -> KnuthForest a -> KnuthForest a+union Nil y = y+union (Fork x xc Nil) y = Fork x xc y+union (Fork x xc xs) y = Fork x xc $ union xs y++intersection :: Eq a => KnuthForest a -> KnuthForest a -> KnuthForest a+intersection Nil _ = Nil+intersection _ Nil = Nil+intersection (Fork x xc xs) (Fork y yc ys)+  | x == y = Fork y (intersection xc yc) (intersection xs ys)+  | otherwise = Nil++-- | Removes the possible subtree on the right, from the left.+difference :: Eq a => KnuthForest a -> KnuthForest a -> KnuthForest a+difference Nil _ = Nil+difference x Nil = x+difference (Fork x xc xs) yss@(Fork y _ _)+  | x == y = Nil+  | otherwise = Fork x (difference xc yss) (difference xs yss)
src/Data/Tree/Rose.hs view
@@ -1,32 +1,56 @@-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE+    TypeFamilies+  , KindSignatures+  , MultiParamTypeClasses+  , FunctionalDependencies+  , FlexibleInstances+  #-}  module Data.Tree.Rose where -import Data.Tree.Rose.Internal- import Data.Tree (Tree (Node)) import Data.Tree.Knuth-import Data.Trie.Pseudo hiding (Nil)-import Data.List.NonEmpty (NonEmpty (..))-import Data.Default-import Data.Functor.Identity+import Data.Tree.Knuth.Forest as KF+import Data.Tree.Set+import qualified Data.Set as Set -class RoseTree (c :: * -> *) (u :: * -> *) (t :: * -> *) | c -> u, c -> t where-  (@->) :: t a -> u (c a) -> c a +type family Head (x :: *) :: *+type family Tail (y :: *) :: *++class RoseTree (c :: * -> *) where+  (@->) :: Head (c a) -> Tail (c a) -> c a+ infixr 9 @-> -instance RoseTree Tree [] Identity where-  (@->) (Identity x) xs = Node x xs -newtype PT t a = PT (t, Maybe a)+-- Data.Tree+type instance Head (Tree a) = a+type instance Tail (Tree a) = [Tree a] -instance Default t => RoseTree (PseudoTrie t) NonEmpty (PT t) where-  (@->) (PT x) xs = More x xs+instance RoseTree Tree where+  (@->) = Node -instance RoseTree KnuthForest Identity Identity where-  (@->) (Identity x) (Identity xs) = Fork x xs Nil++-- Data.Tree.Knuth.Forest+type instance Head (KnuthForest a) = a+type instance Tail (KnuthForest a) = KnuthForest a++instance RoseTree KnuthForest where+  x @-> xs = Fork x xs Nil+++-- Data.Tree.Knuth+type instance Head (KnuthTree a) = a+type instance Tail (KnuthTree a) = KnuthForest a++instance RoseTree KnuthTree where+  x @-> xs = KnuthTree (x,xs)+++-- Data.Tree.Set+type instance Head (SetTree a) = a+type instance Tail (SetTree a) = Set.Set (SetTree a)++instance RoseTree SetTree where+  (@->) = SetTree
− src/Data/Tree/Rose/Internal.hs
@@ -1,3 +0,0 @@-module Data.Tree.Rose.Internal-    (-    ) where
+ src/Data/Tree/Set.hs view
@@ -0,0 +1,107 @@+{-# LANGUAGE+    DeriveFoldable+  , FlexibleInstances+  , MultiParamTypeClasses+  #-}++module Data.Tree.Set where++import Prelude hiding (map, elem, filter)+import qualified Data.Set as Set+import qualified Data.Foldable as F+import qualified Data.Maybe as M+import Data.Monoid hiding ((<>))+import Data.Semigroup+import Data.Semigroup.Foldable+import qualified Data.Set.Class as Sets+import Control.Applicative+import Control.Monad++import Test.QuickCheck+import Test.QuickCheck.Instances+++data SetTree a = SetTree+  { sNode     :: a+  , sChildren :: Set.Set (SetTree a)+  } deriving (Show, Eq, Ord, Foldable)++instance (Ord a, Arbitrary a) => Arbitrary (SetTree a) where+  arbitrary = liftA2 SetTree arbitrary arbitrary++instance Foldable1 SetTree where+  fold1 (SetTree x xs) = F.foldr (\a acc -> sNode a <> acc) x xs++instance Sets.HasSize (SetTree a) where+  size = size++instance Sets.HasSingleton a (SetTree a) where+  singleton = singleton+++-- * Query++-- | set-like alias for @isDescendantOf@.+elem :: Eq a => a -> SetTree a -> Bool+elem = isDescendantOf++size :: SetTree a -> Int+size (SetTree _ xs) = 1 + getSum (F.foldMap (Sum . size) xs)++isChildOf :: Eq a => a -> SetTree a -> Bool+isChildOf x (SetTree _ ys) =+  getAny $ F.foldMap (Any . (x ==) . sNode) ys++isDescendantOf :: Eq a => a -> SetTree a -> Bool+isDescendantOf x (SetTree y ys) =+  (x == y) || getAny (F.foldMap (Any . isDescendantOf x) ys)++-- | Heirarchical analogue to subseteq.+isSubtreeOf :: Eq a => SetTree a -> SetTree a -> Bool+isSubtreeOf xss yss@(SetTree _ ys) =+  xss == yss || getAny (F.foldMap (Any . isSubtreeOf xss) ys)++-- | Bottom-up version+isSubtreeOf' :: Eq a => SetTree a -> SetTree a -> Bool+isSubtreeOf' xss yss@(SetTree _ ys) =+  getAny (F.foldMap (Any . isSubtreeOf' xss) ys) || xss == yss++isProperSubtreeOf :: Eq a => SetTree a -> SetTree a -> Bool+isProperSubtreeOf xss (SetTree _ ys) =+  getAny $ F.foldMap (Any . isSubtreeOf xss) ys++-- | Bottom-up version+isProperSubtreeOf' :: Eq a => SetTree a -> SetTree a -> Bool+isProperSubtreeOf' xss (SetTree _ ys) =+  getAny $ F.foldMap (Any . isSubtreeOf' xss) ys++eqHead :: Eq a => SetTree a -> SetTree a -> Bool+eqHead (SetTree x _) (SetTree y _) = x == y++-- * Construction++insertChild :: Ord a => SetTree a -> SetTree a -> SetTree a+insertChild x (SetTree y ys) = SetTree y $ Set.insert x ys++delete :: Eq a => a -> SetTree a -> Maybe (SetTree a)+delete x = filter (/= x)++singleton :: a -> SetTree a+singleton x = SetTree x Set.empty++-- * Filtering++filter :: Eq a => (a -> Bool) -> SetTree a -> Maybe (SetTree a)+filter p (SetTree x xs) = do+  guard $ p x+  return $ SetTree x $ Set.fromAscList $ M.mapMaybe (filter p) $ Set.toAscList xs++-- * Mapping++map :: Ord b => (a -> b) -> SetTree a -> SetTree b+map f (SetTree x xs) = SetTree (f x) $ Set.map (map f) xs++mapMaybe :: Eq b => (a -> Maybe b) -> SetTree a -> Maybe (SetTree b)+mapMaybe p (SetTree x xs) = do+  x' <- p x+  return $ SetTree x' $ Set.fromAscList $ M.mapMaybe (mapMaybe p) $ Set.toAscList xs
+ test/Data/Tree/RoseSpec.hs view
@@ -0,0 +1,46 @@+module Data.Tree.RoseSpec where++import Data.Tree.Rose++import Data.Monoid+import qualified Data.Tree as T+import qualified Data.Set as Set+import qualified Data.Tree.Set as S+import qualified Data.Tree.Knuth as K+import qualified Data.Tree.Knuth.Forest as KF+++import Test.Tasty+import Test.Tasty.QuickCheck as QC+import Test.QuickCheck+import Test.QuickCheck.Instances+++spec :: TestTree+spec = testGroup "Testing trees..."+  [ testGroup "Data.Tree"+    [ QC.testProperty "element after construction" prop_cons_exists_Tree+    ]+  , testGroup "Data.Tree.Set"+    [ QC.testProperty "element after construction" prop_cons_exists_SetTree+    ]+  , testGroup "Data.Tree.Knuth"+    [ QC.testProperty "element after construction" prop_cons_exists_KnuthTree+    ]+  ]++newtype TreeWithElem t e = TreeWithElem {unTreeWithElem :: (e, t e)}+++prop_cons_exists_Tree :: Int -> [T.Tree Int] -> Bool+prop_cons_exists_Tree x xs = elem' x $ x @-> xs+  where elem' x (T.Node y ys) = x == y || getAny (foldMap (Any . elem' x) ys)++prop_cons_exists_SetTree :: Int -> Set.Set (S.SetTree Int) -> Bool+prop_cons_exists_SetTree x xs = S.elem x $ x @-> xs++prop_cons_exists_KnuthTree :: Int -> KF.KnuthForest Int -> Bool+prop_cons_exists_KnuthTree x xs = K.elem x $ x @-> xs+++-- instance (Arbitrary e
test/Spec.hs view
@@ -1,1 +1,13 @@-{-# OPTIONS_GHC -F -pgmF hspec-discover #-}+module Main where++import Data.Tree.RoseSpec++import Test.Tasty+++main :: IO ()+main = defaultMain tests++tests :: TestTree+tests = testGroup "Testing..."+  [spec]