data-forest-0.1.0.11: test/Main.hs
module Main (main) where
import Control.Applicative (Applicative (pure, (<*>)), (<$>))
import Control.Monad (Functor (fmap), Monad (return, (>>=)))
import Data.Bool (Bool, (&&))
import Data.Char (Char, toUpper)
import Data.Eq (Eq ((==)))
import Data.Foldable (Foldable (null, toList))
import Data.Forest
( Forest (..),
Tree (..),
foldForest,
foldTree,
forest,
leaf,
leaves,
tree,
)
import Data.Function (($), (.))
import Data.List (intercalate, map)
import Data.Semigroup (Semigroup ((<>)))
import Numeric.Natural (Natural)
import System.Exit (die)
import System.IO (IO, putStrLn)
import Text.Show (Show (show))
main :: IO ()
main = dieIfFailures $ do
test 1 $
let example :: Forest Char
example =
forest
[ tree 'a' $ leaves "bc",
tree 'd' $
forest
[ leaf 'e',
tree 'f' $ leaves "g"
]
]
in foldForest
( intercalate ", "
. fmap (\(a, b) -> [a] <> " [" <> b <> "]")
)
example
== "a [b [], c []], d [e [], f [g []]]"
test 2 $
let example :: Tree Char
example =
tree 'a' $
forest
[ tree 'b' $ leaves "cd",
tree 'e' $
forest
[ leaf 'f',
tree 'g' $ leaves "h"
]
]
in foldTree
( \a bs ->
[a] <> " [" <> intercalate ", " bs <> "]"
)
example
== "a [b [c [], d []], e [f [], g [h []]]]"
test 3 $
let example :: Forest Char
example =
forest
[ tree 'a' $ leaves "bc",
tree 'd' $
forest
[ leaf 'e',
tree 'f' $ leaves "g"
]
]
showCharForest f =
intercalate ", " (showCharTree <$> trees f)
where
showCharTree t = case trees (subforest t) of
[] -> [root t]
[t'] -> [root t] <> ": " <> showCharTree t'
_ -> [root t] <> ": (" <> showCharForest (subforest t) <> ")"
in showCharForest example
== "a: (b, c), d: (e, f: g)"
&& showCharForest (fmap toUpper example)
== "A: (B, C), D: (E, F: G)"
test 4 $
let example :: Forest Char
example =
forest
[ tree 'a' $ leaves "bc",
tree 'd' $
forest
[ leaf 'e',
tree 'f' $ leaves "g"
]
]
in toList example == "abcdefg"
dieIfFailures :: Failures a -> IO a
dieIfFailures (Failures fs x) =
if null fs
then do putStrLn "💯"; return x
else die $ intercalate " " (map (("🔥" <>) . show) fs)
type TestNumber = Natural
test :: TestNumber -> Bool -> Failures ()
test n t = Failures (if t then [] else [n]) ()
data Failures a = Failures [TestNumber] a
instance Functor Failures where
fmap f (Failures a x) = Failures a (f x)
instance Applicative Failures where
pure x = Failures [] x
Failures a f <*> Failures b x = Failures (a <> b) (f x)
instance Monad Failures where
Failures a x >>= f = let Failures b y = f x in Failures (a <> b) y