areTheyEqual :: RTuple -> RTuple -> Bool
areTheyEqual t1 t2 =  -- foldrWithKey :: (k -> v -> a -> a) -> a -> HashMap k v -> a
    HM.foldrWithKey (accumulator) True t1
        where 
            accumulator :: ColumnName -> RDataType -> Bool -> Bool
            accumulator colName val acc = 
                case val of
                    Null -> 
                            case (t2<!>colName) of
                                Null -> acc -- -- i.e., True && acc ,if both columns are Null then return equality
                                _    -> False -- i.e., False && acc
                    _    -> case (t2<!>colName) of
                                Null -> False -- i.e., False && acc
                                _    -> (val == t2<!>colName) && acc -- else compare them as normal

                        -- *** NOTE ***
                        -- the following piece of code does not work because val == Null always returns False !!!!

                        -- if (val == Null) && (t2<!>colName == Null) 
                        --     then acc -- i.e., True && acc
                        --     -- else compare them as normal
                        --     else  (val == t2<!>colName) && acc

{-
runDiff rt1 rt2 = 
    let ls1 = V.toList rt1
        ls2 = V.toList rt2
        resultLs = ls1 Data.List.\\ ls2
    in  V.fromList resultLs
-}
areTheyEqual :: RTuple -> RTuple -> Bool
areTheyEqual t1 t2 =  -- foldrWithKey :: (k -> v -> a -> a) -> a -> HashMap k v -> a
    HM.foldrWithKey (accumulator) True t1
        where 
            accumulator :: ColumnName -> RDataType -> Bool -> Bool
            accumulator colName val acc = 
                case val of
                    Null -> 
                            case (t2<!>colName) of
                                Null -> acc -- -- i.e., True && acc ,if both columns are Null then return equality
                                _    -> False -- i.e., False && acc
                    _    -> case (t2<!>colName) of
                                Null -> False -- i.e., False && acc
                                _    -> (val == t2<!>colName) && acc -- else compare them as normal

                        -- *** NOTE ***
                        -- the following piece of code does not work because val == Null always returns False !!!!

                        -- if (val == Null) && (t2<!>colName == Null) 
                        --     then acc -- i.e., True && acc
                        --     -- else compare them as normal
                        --     else  (val == t2<!>colName) && acc

{-
runDiff rt1 rt2 = 
    let ls1 = V.toList rt1
        ls2 = V.toList rt2
        resultLs = ls1 Data.List.\\ ls2
    in  V.fromList resultLs
-}
areTheyEqual t1 t2 =  -- foldrWithKey :: (k -> v -> a -> a) -> a -> HashMap k v -> a
    HM.foldrWithKey (accumulator) True t1
        where 
            accumulator :: ColumnName -> RDataType -> Bool -> Bool
            accumulator colName val acc = 
                case val of
                    Null -> 
                            case (t2<!>colName) of
                                Null -> acc -- -- i.e., True && acc ,if both columns are Null then return equality
                                _    -> False -- i.e., False && acc
                    _    -> case (t2<!>colName) of
                                Null -> False -- i.e., False && acc
                                _    -> (val == t2<!>colName) && acc -- else compare them as normal

                        -- *** NOTE ***
                        -- the following piece of code does not work because val == Null always returns False !!!!

                        -- if (val == Null) && (t2<!>colName == Null) 
                        --     then acc -- i.e., True && acc
                        --     -- else compare them as normal
                        --     else  (val == t2<!>colName) && acc

{-
runDiff rt1 rt2 = 
    let ls1 = V.toList rt1
        ls2 = V.toList rt2
        resultLs = ls1 Data.List.\\ ls2
    in  V.fromList resultLs
-}