{- -----------------------------------------------------------------------------
Copyright 2020 Kevin P. Barry

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
----------------------------------------------------------------------------- -}

-- Author: Kevin P. Barry [ta0kira@gmail.com]

module Test.MergeTree (tests) where

import Control.Monad (when)
import Data.Char (toUpper)

import Base.CompilerError
import Base.TrackedErrors
import Base.MergeTree
import Base.Mergeable


tests :: [IO (TrackedErrors ())]
tests :: [IO (TrackedErrors ())]
tests = [
   MergeTree Int
-> (MergeTree Int -> MergeTree Int)
-> MergeTree Int
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny ([MergeTree Int] -> MergeTree Int)
-> [MergeTree Int] -> MergeTree Int
forall a b. (a -> b) -> a -> b
$ (Int -> MergeTree Int) -> [Int] -> [MergeTree Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf [Int
2,Int
4,Int
6]) ((Int -> Int) -> MergeTree Int -> MergeTree Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
2))
              ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny ([MergeTree Int] -> MergeTree Int)
-> [MergeTree Int] -> MergeTree Int
forall a b. (a -> b) -> a -> b
$ (Int -> MergeTree Int) -> [Int] -> [MergeTree Int]
forall a b. (a -> b) -> [a] -> [b]
map Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf [Int
1..Int
3] :: MergeTree Int),
   MergeTree Int
-> (MergeTree Int -> MergeTree Int)
-> MergeTree Int
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll ([MergeTree Int] -> MergeTree Int)
-> [MergeTree Int] -> MergeTree Int
forall a b. (a -> b) -> a -> b
$ (Int -> MergeTree Int) -> [Int] -> [MergeTree Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf [Int
2,Int
4,Int
6]) ((Int -> Int) -> MergeTree Int -> MergeTree Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
2))
              ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll ([MergeTree Int] -> MergeTree Int)
-> [MergeTree Int] -> MergeTree Int
forall a b. (a -> b) -> a -> b
$ (Int -> MergeTree Int) -> [Int] -> [MergeTree Int]
forall a b. (a -> b) -> [a] -> [b]
map Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf [Int
1..Int
3] :: MergeTree Int),

   MergeTree Int
-> (MergeTree Int -> MergeTree Int)
-> MergeTree Int
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch (Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
1) MergeTree Int -> MergeTree Int
forall a. a -> a
id ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
1,MergeTree Int
forall a. Bounded a => a
minBound] :: MergeTree Int),
   MergeTree Int
-> (MergeTree Int -> MergeTree Int)
-> MergeTree Int
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch (Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
1) MergeTree Int -> MergeTree Int
forall a. a -> a
id ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
1,MergeTree Int
forall a. Bounded a => a
maxBound] :: MergeTree Int),

   MergeTree Int
-> MergeTree Int -> MergeTree Int -> IO (TrackedErrors ())
forall a. (Eq a, Show a) => a -> a -> a -> IO (TrackedErrors ())
checkMatch2 ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
1,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
2,[MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
3,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
4]])
               ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
1,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
2,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
3,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
4])
               ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [[MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
1],Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
2,[MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
3,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
4]] :: MergeTree Int),
   MergeTree Int
-> MergeTree Int -> MergeTree Int -> IO (TrackedErrors ())
forall a. (Eq a, Show a) => a -> a -> a -> IO (TrackedErrors ())
checkMatch2 ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
1,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
2,[MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
3,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
4]])
               ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
1,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
2,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
3,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
4])
               ([MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
1],Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
2,[MergeTree Int] -> MergeTree Int
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
3,Int -> MergeTree Int
forall a. a -> MergeTree a
mergeLeaf Int
4]] :: MergeTree Int),

   -- a*(b&c)*(d|e) = (a*b&a*c)*(d|e) = (a*b*(d|e)&a*c*(d|e)) = (a*b*d|a*b*e)&(a*c*d|a*c*e)
   MergeTree [Char]
-> ([MergeTree Char] -> MergeTree [Char])
-> [MergeTree Char]
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch ([MergeTree [Char]] -> MergeTree [Char]
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree [Char]] -> MergeTree [Char]
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"abd",[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"abe"],[MergeTree [Char]] -> MergeTree [Char]
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"acd",[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"ace"]]) [MergeTree Char] -> MergeTree [Char]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence
              [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c'],[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'd',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'e']],

   MergeTree Char
-> (MergeTree Char -> MergeTree Char)
-> MergeTree Char
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'A'],
                         [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'B'],
                                   [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'C']]])
              (\MergeTree Char
x -> do
                Char
x' <- MergeTree Char
x
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall (m :: * -> *) a. Monad m => a -> m a
return Char
x',Char -> MergeTree Char
forall (m :: * -> *) a. Monad m => a -> m a
return (Char -> Char
toUpper Char
x')])
              ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c']]),

    [MergeTree Char]
-> (MergeTree [Char] -> [MergeTree Char])
-> MergeTree [Char]
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],
                          [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c',
                                    [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'd',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'e']],
                          Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'f']]
               MergeTree [Char] -> [MergeTree Char]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence  -- MergeTree [Char] -> [MergeTree Char]
               ([MergeTree [Char]] -> MergeTree [Char]
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree [Char]] -> MergeTree [Char]
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"a",[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"b"],
                          [MergeTree [Char]] -> MergeTree [Char]
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"c",
                                    [MergeTree [Char]] -> MergeTree [Char]
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"d",[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"e"]],
                          [Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"f"]),

    MergeTree [Char]
-> ([MergeTree Char] -> MergeTree [Char])
-> [MergeTree Char]
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch ([MergeTree [Char]] -> MergeTree [Char]
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree [Char]] -> MergeTree [Char]
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"a",[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"b"],
                          [MergeTree [Char]] -> MergeTree [Char]
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"c",
                                    [MergeTree [Char]] -> MergeTree [Char]
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"d",[Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"e"]],
                          [Char] -> MergeTree [Char]
forall a. a -> MergeTree a
mergeLeaf [Char]
"f"])
               [MergeTree Char] -> MergeTree [Char]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence  -- [MergeTree Char] -> MergeTree [Char]
               [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],
                          [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c',
                                    [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'd',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'e']],
                          Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'f']],

    MergeTree Char
-> (MergeTree Char -> MergeTree Char)
-> MergeTree Char
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'A',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'B'],
                          [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'C',
                                    [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'D',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'E']],
                          Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'F'])
               (Char -> Char
toUpper (Char -> Char) -> MergeTree Char -> MergeTree Char
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],
                          [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c',
                                    [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'd',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'e']],
                          Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'f']),

    MergeTree Char
-> (MergeTree (Char -> Char) -> MergeTree Char)
-> MergeTree (Char -> Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'A',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'B'],
                          [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'C',
                                    [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'D',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'E']],
                          Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'F'])
               (([MergeTree ((Char -> Char) -> Char)]
-> MergeTree ((Char -> Char) -> Char)
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree ((Char -> Char) -> Char)]
-> MergeTree ((Char -> Char) -> Char)
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [((Char -> Char) -> Char) -> MergeTree ((Char -> Char) -> Char)
forall a. a -> MergeTree a
mergeLeaf ((Char -> Char) -> Char -> Char
forall a b. (a -> b) -> a -> b
$Char
'a'),((Char -> Char) -> Char) -> MergeTree ((Char -> Char) -> Char)
forall a. a -> MergeTree a
mergeLeaf ((Char -> Char) -> Char -> Char
forall a b. (a -> b) -> a -> b
$Char
'b')],
                           [MergeTree ((Char -> Char) -> Char)]
-> MergeTree ((Char -> Char) -> Char)
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [((Char -> Char) -> Char) -> MergeTree ((Char -> Char) -> Char)
forall a. a -> MergeTree a
mergeLeaf ((Char -> Char) -> Char -> Char
forall a b. (a -> b) -> a -> b
$Char
'c'),
                                     [MergeTree ((Char -> Char) -> Char)]
-> MergeTree ((Char -> Char) -> Char)
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [((Char -> Char) -> Char) -> MergeTree ((Char -> Char) -> Char)
forall a. a -> MergeTree a
mergeLeaf ((Char -> Char) -> Char -> Char
forall a b. (a -> b) -> a -> b
$Char
'd'),((Char -> Char) -> Char) -> MergeTree ((Char -> Char) -> Char)
forall a. a -> MergeTree a
mergeLeaf ((Char -> Char) -> Char -> Char
forall a b. (a -> b) -> a -> b
$Char
'e')]],
                           ((Char -> Char) -> Char) -> MergeTree ((Char -> Char) -> Char)
forall a. a -> MergeTree a
mergeLeaf ((Char -> Char) -> Char -> Char
forall a b. (a -> b) -> a -> b
$Char
'f')]) MergeTree ((Char -> Char) -> Char)
-> MergeTree (Char -> Char) -> MergeTree Char
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>)
               ((Char -> Char) -> MergeTree (Char -> Char)
forall a. a -> MergeTree a
mergeLeaf Char -> Char
toUpper),

    Bool
-> ((MergeTree (), MergeTree ()) -> Bool)
-> (MergeTree (), MergeTree ())
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
True
               ((MergeTree () -> MergeTree () -> Bool)
-> (MergeTree (), MergeTree ()) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree () -> MergeTree () -> Bool)
 -> (MergeTree (), MergeTree ()) -> Bool)
-> (MergeTree () -> MergeTree () -> Bool)
-> (MergeTree (), MergeTree ())
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree ()) -> T (MergeTree ()) -> Bool)
-> MergeTree ()
-> MergeTree ()
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree ()) -> T (MergeTree ()) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               (MergeTree ()
forall a. Bounded a => a
minBound :: MergeTree (),MergeTree ()
forall a. Bounded a => a
minBound :: MergeTree ()),
    Bool
-> ((MergeTree (), MergeTree ()) -> Bool)
-> (MergeTree (), MergeTree ())
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
True
               ((MergeTree () -> MergeTree () -> Bool)
-> (MergeTree (), MergeTree ()) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree () -> MergeTree () -> Bool)
 -> (MergeTree (), MergeTree ()) -> Bool)
-> (MergeTree () -> MergeTree () -> Bool)
-> (MergeTree (), MergeTree ())
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree ()) -> T (MergeTree ()) -> Bool)
-> MergeTree ()
-> MergeTree ()
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree ()) -> T (MergeTree ()) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               (MergeTree ()
forall a. Bounded a => a
maxBound :: MergeTree (),MergeTree ()
forall a. Bounded a => a
maxBound :: MergeTree ()),
    Bool
-> ((MergeTree (), MergeTree ()) -> Bool)
-> (MergeTree (), MergeTree ())
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
True
               ((MergeTree () -> MergeTree () -> Bool)
-> (MergeTree (), MergeTree ()) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree () -> MergeTree () -> Bool)
 -> (MergeTree (), MergeTree ()) -> Bool)
-> (MergeTree () -> MergeTree () -> Bool)
-> (MergeTree (), MergeTree ())
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree ()) -> T (MergeTree ()) -> Bool)
-> MergeTree ()
-> MergeTree ()
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree ()) -> T (MergeTree ()) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               (MergeTree ()
forall a. Bounded a => a
minBound :: MergeTree (),MergeTree ()
forall a. Bounded a => a
maxBound :: MergeTree ()),
    Bool
-> ((MergeTree (), MergeTree ()) -> Bool)
-> (MergeTree (), MergeTree ())
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
False
               ((MergeTree () -> MergeTree () -> Bool)
-> (MergeTree (), MergeTree ()) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree () -> MergeTree () -> Bool)
 -> (MergeTree (), MergeTree ()) -> Bool)
-> (MergeTree () -> MergeTree () -> Bool)
-> (MergeTree (), MergeTree ())
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree ()) -> T (MergeTree ()) -> Bool)
-> MergeTree ()
-> MergeTree ()
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree ()) -> T (MergeTree ()) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               (MergeTree ()
forall a. Bounded a => a
maxBound :: MergeTree (),MergeTree ()
forall a. Bounded a => a
minBound :: MergeTree ()),

    Bool
-> ((MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char, MergeTree Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
True
               ((MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree Char -> MergeTree Char -> Bool)
 -> (MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char)
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree Char) -> T (MergeTree Char) -> Bool)
-> MergeTree Char
-> MergeTree Char
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree Char) -> T (MergeTree Char) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c']),
    Bool
-> ((MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char, MergeTree Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
True
               ((MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree Char -> MergeTree Char -> Bool)
 -> (MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char)
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree Char) -> T (MergeTree Char) -> Bool)
-> MergeTree Char
-> MergeTree Char
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree Char) -> T (MergeTree Char) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c'],
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b']),
    Bool
-> ((MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char, MergeTree Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
False
               ((MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree Char -> MergeTree Char -> Bool)
 -> (MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char)
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree Char) -> T (MergeTree Char) -> Bool)
-> MergeTree Char
-> MergeTree Char
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree Char) -> T (MergeTree Char) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c']),
    Bool
-> ((MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char, MergeTree Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
False
               ((MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree Char -> MergeTree Char -> Bool)
 -> (MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char)
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree Char) -> T (MergeTree Char) -> Bool)
-> MergeTree Char
-> MergeTree Char
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree Char) -> T (MergeTree Char) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c'],
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b']),
    Bool
-> ((MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char, MergeTree Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
True
               ((MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree Char -> MergeTree Char -> Bool)
 -> (MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char)
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree Char) -> T (MergeTree Char) -> Bool)
-> MergeTree Char
-> MergeTree Char
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree Char) -> T (MergeTree Char) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b']),
    Bool
-> ((MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char, MergeTree Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
True
               ((MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree Char -> MergeTree Char -> Bool)
 -> (MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char)
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree Char) -> T (MergeTree Char) -> Bool)
-> MergeTree Char
-> MergeTree Char
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree Char) -> T (MergeTree Char) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b']),

    Bool
-> ((MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char, MergeTree Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
True
               ((MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree Char -> MergeTree Char -> Bool)
 -> (MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char)
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree Char) -> T (MergeTree Char) -> Bool)
-> MergeTree Char
-> MergeTree Char
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree Char) -> T (MergeTree Char) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c']),
    Bool
-> ((MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char, MergeTree Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
True
               ((MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree Char -> MergeTree Char -> Bool)
 -> (MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char)
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree Char) -> T (MergeTree Char) -> Bool)
-> MergeTree Char
-> MergeTree Char
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree Char) -> T (MergeTree Char) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c'],
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b']),
    Bool
-> ((MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char, MergeTree Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
True
               ((MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree Char -> MergeTree Char -> Bool)
 -> (MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char)
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree Char) -> T (MergeTree Char) -> Bool)
-> MergeTree Char
-> MergeTree Char
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree Char) -> T (MergeTree Char) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c'],
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c']),
    Bool
-> ((MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char, MergeTree Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
True
               ((MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree Char -> MergeTree Char -> Bool)
 -> (MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char)
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree Char) -> T (MergeTree Char) -> Bool)
-> MergeTree Char
-> MergeTree Char
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree Char) -> T (MergeTree Char) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c'],
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [[MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'c']),
    Bool
-> ((MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char, MergeTree Char)
-> IO (TrackedErrors ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch Bool
False
               ((MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((MergeTree Char -> MergeTree Char -> Bool)
 -> (MergeTree Char, MergeTree Char) -> Bool)
-> (MergeTree Char -> MergeTree Char -> Bool)
-> (MergeTree Char, MergeTree Char)
-> Bool
forall a b. (a -> b) -> a -> b
$ ([Bool] -> Bool)
-> ([Bool] -> Bool)
-> (T (MergeTree Char) -> T (MergeTree Char) -> Bool)
-> MergeTree Char
-> MergeTree Char
-> Bool
forall a b c.
(PreserveMerge a, PreserveMerge b) =>
([c] -> c) -> ([c] -> c) -> (T a -> T b -> c) -> a -> b -> c
pairMergeTree [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Bool] -> Bool
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll T (MergeTree Char) -> T (MergeTree Char) -> Bool
forall a. Eq a => a -> a -> Bool
(==))
               ([MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAny [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'],
                [MergeTree Char] -> MergeTree Char
forall a (f :: * -> *). (Mergeable a, Foldable f) => f a -> a
mergeAll [Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'a',Char -> MergeTree Char
forall a. a -> MergeTree a
mergeLeaf Char
'b'])
 ]

oddError :: Int -> TrackedErrors Int
oddError :: Int -> TrackedErrors Int
oddError Int
x = do
  Bool -> TrackedErrors () -> TrackedErrors ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int -> Bool
forall a. Integral a => a -> Bool
odd Int
x) (TrackedErrors () -> TrackedErrors ())
-> TrackedErrors () -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [Char] -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => [Char] -> m a
compilerErrorM ([Char] -> TrackedErrors ()) -> [Char] -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
x [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" is odd"
  Int -> TrackedErrors Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
x

oddError2 :: Int -> TrackedErrors [Int]
oddError2 :: Int -> TrackedErrors [Int]
oddError2 = (Int -> [Int]) -> TrackedErrors Int -> TrackedErrors [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:[]) (TrackedErrors Int -> TrackedErrors [Int])
-> (Int -> TrackedErrors Int) -> Int -> TrackedErrors [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> TrackedErrors Int
oddError

checkMatch :: (Eq b, Show b) => b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch :: b -> (a -> b) -> a -> IO (TrackedErrors ())
checkMatch b
x a -> b
f a
y = let y' :: b
y' = a -> b
f a
y in
  TrackedErrors () -> IO (TrackedErrors ())
forall (m :: * -> *) a. Monad m => a -> m a
return (TrackedErrors () -> IO (TrackedErrors ()))
-> TrackedErrors () -> IO (TrackedErrors ())
forall a b. (a -> b) -> a -> b
$ if b
x b -> b -> Bool
forall a. Eq a => a -> a -> Bool
/= b
y'
              then [Char] -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => [Char] -> m a
compilerErrorM ([Char] -> TrackedErrors ()) -> [Char] -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Expected " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ b -> [Char]
forall a. Show a => a -> [Char]
show b
x [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" but got " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ b -> [Char]
forall a. Show a => a -> [Char]
show b
y'
              else () -> TrackedErrors ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

checkMatch2 :: (Eq a, Show a) => a -> a -> a -> IO (TrackedErrors ())
checkMatch2 :: a -> a -> a -> IO (TrackedErrors ())
checkMatch2 a
x a
y a
z = TrackedErrors () -> IO (TrackedErrors ())
forall (m :: * -> *) a. Monad m => a -> m a
return (TrackedErrors () -> IO (TrackedErrors ()))
-> TrackedErrors () -> IO (TrackedErrors ())
forall a b. (a -> b) -> a -> b
$ do
  Bool -> TrackedErrors () -> TrackedErrors ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
z) (TrackedErrors () -> TrackedErrors ())
-> TrackedErrors () -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [Char] -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => [Char] -> m a
compilerErrorM ([Char] -> TrackedErrors ()) -> [Char] -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Expected " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
x [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" but got " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
z
  Bool -> TrackedErrors () -> TrackedErrors ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (a
y a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
z) (TrackedErrors () -> TrackedErrors ())
-> TrackedErrors () -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [Char] -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => [Char] -> m a
compilerErrorM ([Char] -> TrackedErrors ()) -> [Char] -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Expected something besides " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
y

checkSuccess :: (Eq b, Show b) => b -> (a -> TrackedErrors b) -> a -> IO (TrackedErrors ())
checkSuccess :: b -> (a -> TrackedErrors b) -> a -> IO (TrackedErrors ())
checkSuccess b
x a -> TrackedErrors b
f a
y = let y' :: TrackedErrors b
y' = a -> TrackedErrors b
f a
y in
  TrackedErrors () -> IO (TrackedErrors ())
forall (m :: * -> *) a. Monad m => a -> m a
return (TrackedErrors () -> IO (TrackedErrors ()))
-> TrackedErrors () -> IO (TrackedErrors ())
forall a b. (a -> b) -> a -> b
$ if TrackedErrors b -> Bool
forall (t :: (* -> *) -> * -> *) a.
(ErrorContextT t, ErrorContextM (t Identity)) =>
t Identity a -> Bool
isCompilerError TrackedErrors b
y' Bool -> Bool -> Bool
|| TrackedErrors b -> b
forall a. TrackedErrors a -> a
getCompilerSuccess TrackedErrors b
y' b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
x
              then TrackedErrors b
y' TrackedErrors b -> TrackedErrors () -> TrackedErrors ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> TrackedErrors ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
              else [Char] -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => [Char] -> m a
compilerErrorM ([Char] -> TrackedErrors ()) -> [Char] -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Expected value " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ b -> [Char]
forall a. Show a => a -> [Char]
show b
x [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" but got value " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ b -> [Char]
forall a. Show a => a -> [Char]
show (TrackedErrors b -> b
forall a. TrackedErrors a -> a
getCompilerSuccess TrackedErrors b
y')

checkError :: Show b => String -> (a -> TrackedErrors b) -> a -> IO (TrackedErrors ())
checkError :: [Char] -> (a -> TrackedErrors b) -> a -> IO (TrackedErrors ())
checkError [Char]
e a -> TrackedErrors b
f a
y = let y' :: TrackedErrors b
y' = a -> TrackedErrors b
f a
y in
  TrackedErrors () -> IO (TrackedErrors ())
forall (m :: * -> *) a. Monad m => a -> m a
return (TrackedErrors () -> IO (TrackedErrors ()))
-> TrackedErrors () -> IO (TrackedErrors ())
forall a b. (a -> b) -> a -> b
$ if Bool -> Bool
not (TrackedErrors b -> Bool
forall (t :: (* -> *) -> * -> *) a.
(ErrorContextT t, ErrorContextM (t Identity)) =>
t Identity a -> Bool
isCompilerError TrackedErrors b
y')
              then [Char] -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => [Char] -> m a
compilerErrorM ([Char] -> TrackedErrors ()) -> [Char] -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Expected error \"" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
e [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\" but got value " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ b -> [Char]
forall a. Show a => a -> [Char]
show (TrackedErrors b -> b
forall a. TrackedErrors a -> a
getCompilerSuccess TrackedErrors b
y')
              else if CompilerMessage -> [Char]
forall a. Show a => a -> [Char]
show (TrackedErrors b -> CompilerMessage
forall a. TrackedErrors a -> CompilerMessage
getCompilerError TrackedErrors b
y') [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
e
                      then () -> TrackedErrors ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                      else [Char] -> TrackedErrors ()
forall (m :: * -> *) a. ErrorContextM m => [Char] -> m a
compilerErrorM ([Char] -> TrackedErrors ()) -> [Char] -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Expected error \"" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
e [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\" but got error \"" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ CompilerMessage -> [Char]
forall a. Show a => a -> [Char]
show (TrackedErrors b -> CompilerMessage
forall a. TrackedErrors a -> CompilerMessage
getCompilerError TrackedErrors b
y') [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\""