{-# LANGUAGE
    TypeFamilies
  , KindSignatures
  , MultiParamTypeClasses
  , FunctionalDependencies
  , FlexibleInstances
  #-}

module Data.Tree.Rose where

import Data.Tree (Tree (Node))
import Data.Tree.Knuth
import Data.Tree.Knuth.Forest as KF
import Data.Tree.Set
import qualified Data.Set as Set


type family Head (x :: *) :: *
type family Tail (y :: *) :: *

class RoseTree (c :: * -> *) where
  (@->) :: Head (c a) -> Tail (c a) -> c a

infixr 9 @->


-- Data.Tree
type instance Head (Tree a) = a
type instance Tail (Tree a) = [Tree a]

instance RoseTree Tree where
  (@->) = Node


-- 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