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

{-# LANGUAGE Safe #-}

module Test.MergeTree (tests) where

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

import Base.CompileError
import Base.CompileInfo
import Base.MergeTree
import Base.Mergeable


tests :: [IO (CompileInfo ())]
tests :: [IO (CompileInfo ())]
tests = [
   MergeTree Int
-> (MergeTree Int -> MergeTree Int)
-> MergeTree Int
-> IO (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall a. (Eq a, Show a) => a -> a -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall a. (Eq a, Show a) => a -> a -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 (CompileInfo ())
forall b a.
(Eq b, Show b) =>
b -> (a -> b) -> a -> IO (CompileInfo ())
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 -> CompileInfo Int
oddError :: Int -> CompileInfo Int
oddError Int
x = do
  Bool -> CompileInfo () -> CompileInfo ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int -> Bool
forall a. Integral a => a -> Bool
odd Int
x) (CompileInfo () -> CompileInfo ())
-> CompileInfo () -> CompileInfo ()
forall a b. (a -> b) -> a -> b
$ [Char] -> CompileInfo ()
forall (m :: * -> *) a. CompileErrorM m => [Char] -> m a
compileErrorM ([Char] -> CompileInfo ()) -> [Char] -> CompileInfo ()
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 -> CompileInfo Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
x

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

checkMatch :: (Eq b, Show b) => b -> (a -> b) -> a -> IO (CompileInfo ())
checkMatch :: b -> (a -> b) -> a -> IO (CompileInfo ())
checkMatch b
x a -> b
f a
y = let y' :: b
y' = a -> b
f a
y in
  CompileInfo () -> IO (CompileInfo ())
forall (m :: * -> *) a. Monad m => a -> m a
return (CompileInfo () -> IO (CompileInfo ()))
-> CompileInfo () -> IO (CompileInfo ())
forall a b. (a -> b) -> a -> b
$ if b
x b -> b -> Bool
forall a. Eq a => a -> a -> Bool
/= b
y'
              then [Char] -> CompileInfo ()
forall (m :: * -> *) a. CompileErrorM m => [Char] -> m a
compileErrorM ([Char] -> CompileInfo ()) -> [Char] -> CompileInfo ()
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 () -> CompileInfo ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

checkMatch2 :: (Eq a, Show a) => a -> a -> a -> IO (CompileInfo ())
checkMatch2 :: a -> a -> a -> IO (CompileInfo ())
checkMatch2 a
x a
y a
z = CompileInfo () -> IO (CompileInfo ())
forall (m :: * -> *) a. Monad m => a -> m a
return (CompileInfo () -> IO (CompileInfo ()))
-> CompileInfo () -> IO (CompileInfo ())
forall a b. (a -> b) -> a -> b
$ do
  Bool -> CompileInfo () -> CompileInfo ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
z) (CompileInfo () -> CompileInfo ())
-> CompileInfo () -> CompileInfo ()
forall a b. (a -> b) -> a -> b
$ [Char] -> CompileInfo ()
forall (m :: * -> *) a. CompileErrorM m => [Char] -> m a
compileErrorM ([Char] -> CompileInfo ()) -> [Char] -> CompileInfo ()
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 -> CompileInfo () -> CompileInfo ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (a
y a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
z) (CompileInfo () -> CompileInfo ())
-> CompileInfo () -> CompileInfo ()
forall a b. (a -> b) -> a -> b
$ [Char] -> CompileInfo ()
forall (m :: * -> *) a. CompileErrorM m => [Char] -> m a
compileErrorM ([Char] -> CompileInfo ()) -> [Char] -> CompileInfo ()
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 -> CompileInfo b) -> a -> IO (CompileInfo ())
checkSuccess :: b -> (a -> CompileInfo b) -> a -> IO (CompileInfo ())
checkSuccess b
x a -> CompileInfo b
f a
y = let y' :: CompileInfo b
y' = a -> CompileInfo b
f a
y in
  CompileInfo () -> IO (CompileInfo ())
forall (m :: * -> *) a. Monad m => a -> m a
return (CompileInfo () -> IO (CompileInfo ()))
-> CompileInfo () -> IO (CompileInfo ())
forall a b. (a -> b) -> a -> b
$ if CompileInfo b -> Bool
forall a. CompileInfo a -> Bool
isCompileError CompileInfo b
y' Bool -> Bool -> Bool
|| CompileInfo b -> b
forall a. CompileInfo a -> a
getCompileSuccess CompileInfo b
y' b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
x
              then CompileInfo b
y' CompileInfo b -> CompileInfo () -> CompileInfo ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> CompileInfo ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
              else [Char] -> CompileInfo ()
forall (m :: * -> *) a. CompileErrorM m => [Char] -> m a
compileErrorM ([Char] -> CompileInfo ()) -> [Char] -> CompileInfo ()
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 (CompileInfo b -> b
forall a. CompileInfo a -> a
getCompileSuccess CompileInfo b
y')

checkError :: Show b => String -> (a -> CompileInfo b) -> a -> IO (CompileInfo ())
checkError :: [Char] -> (a -> CompileInfo b) -> a -> IO (CompileInfo ())
checkError [Char]
e a -> CompileInfo b
f a
y = let y' :: CompileInfo b
y' = a -> CompileInfo b
f a
y in
  CompileInfo () -> IO (CompileInfo ())
forall (m :: * -> *) a. Monad m => a -> m a
return (CompileInfo () -> IO (CompileInfo ()))
-> CompileInfo () -> IO (CompileInfo ())
forall a b. (a -> b) -> a -> b
$ if Bool -> Bool
not (CompileInfo b -> Bool
forall a. CompileInfo a -> Bool
isCompileError CompileInfo b
y')
              then [Char] -> CompileInfo ()
forall (m :: * -> *) a. CompileErrorM m => [Char] -> m a
compileErrorM ([Char] -> CompileInfo ()) -> [Char] -> CompileInfo ()
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 (CompileInfo b -> b
forall a. CompileInfo a -> a
getCompileSuccess CompileInfo b
y')
              else if CompileMessage -> [Char]
forall a. Show a => a -> [Char]
show (CompileInfo b -> CompileMessage
forall a. CompileInfo a -> CompileMessage
getCompileError CompileInfo b
y') [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
e
                      then () -> CompileInfo ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                      else [Char] -> CompileInfo ()
forall (m :: * -> *) a. CompileErrorM m => [Char] -> m a
compileErrorM ([Char] -> CompileInfo ()) -> [Char] -> CompileInfo ()
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]
++ CompileMessage -> [Char]
forall a. Show a => a -> [Char]
show (CompileInfo b -> CompileMessage
forall a. CompileInfo a -> CompileMessage
getCompileError CompileInfo b
y') [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\""