{-# LANGUAGE UnicodeSyntax #-} {-# OPTIONS_HADDOCK hide #-} module System.Directory.Layout.Internal ( DL(..), Layout ) where import Control.Applicative import Control.Arrow import Data.Text (Text) import Test.QuickCheck -- | Abstract data type representing directory tree is nice data DL f = E f | F FilePath (Maybe Text) (DL f) | D FilePath (DL ()) (DL f) deriving (Show, Read) -- | But type synonym is nicer type Layout = DL () instance Functor DL where fmap f (E x) = E (f x) fmap f (F fp c x) = F fp c (fmap f x) fmap f (D fp x y) = D fp x (fmap f y) instance Monad DL where return = E E x >>= f = f x F fp c x >>= f = F fp c (x >>= f) D fp x y >>= f = D fp x (y >>= f) -- Make arbitrary layout of reasonable size -- Frequencies are pretty /arbitrary/ chosen with layout construction termination in mind instance Arbitrary a ⇒ Arbitrary (DL a) where arbitrary = snd <$> generator 0 where generator ∷ Arbitrary a ⇒ Int → Gen (Int, DL a) generator n = frequency [ (8, do (n', g') ← generator (succ n) generator n' <&> second (D (show n) g')) , (20, generator (succ n) <&> second (F (show n) Nothing)) , (10, arbitrary <&> \r → (n, E r)) ] where (<&>) = flip fmap