module Crossed where -- since the four matches are disjoint, it is possible to swap them -- to merge matches before removing guards. crossed (h:t1) x | h == 0 = x crossed [] y | y > 0 = 1 crossed (h:t2) z | otherwise = -z crossed [] v | v < 0 = -1

module Crossed where -- since the four matches are disjoint, it is possible to swap them -- to merge matches before removing guards. crossed ((h : xx_0)) xx_1 = if h == 0 then xx_1 else -xx_1 crossed [] xx_2 = if xx_2 > 0 then 1 else if xx_2 < 0 then -1 else error "UnMatched Pattern"

module Decl where -- The declaration will be converted into a let inside the expressions. f x y | x < 0 = x where x = y f u v | u > 0 = -v f a b | otherwise = 0

module Decl where -- The declaration will be converted into a let inside the expressions. f xx_2 xx_3 = if let x = xx_3 in x < 0 then let x = xx_3 in x else if xx_2 > 0 then -xx_3 else 0

module IrrPat where import Maybe -- A let will be added to the expressions. func :: Maybe Int -> Int func ~(v@(Just x)) | isJust v = x func v | otherwise = 0

module IrrPat where import Maybe -- A let will be added to the expressions. func :: Maybe Int -> Int func xx_1 = if let (v@(Just x)) = xx_1 in isJust v then let (v@(Just x)) = xx_1 in x else 0

module A where data X a = A | B a | C {x,y::a} -- only the second match will not be merged, and the otherwise case is not -- present in none of the expressions. f (C {x = myx}) ([],0) x | x < 0 = myx f A (lst,0) x | x == 1 = head lst -- disjoint from others f (C a b) r@([] ,0) x | x > 0 = snd r f (B 0) (a,b) x | x == 2 = b f ((B 0)) (a,c) x | x == 3 = -c

module A where data X a = A | B a | C {x,y::a} -- only the second match will not be merged, and the otherwise case is not -- present in none of the expressions. f A (lst, 0) x = if x == 1 then head lst else error "UnMatched Pattern" f (C xx_0 xx_1) xx_2@([], 0) x = if x < 0 then xx_0 else if x > 0 then snd xx_2 else error "UnMatched Pattern" f (B 0) (a, xx_3) x = if x == 2 then xx_3 else if x == 3 then -xx_3 else error "UnMatched Pattern"

module B where data X a = A | B a | C {x,y::a} -- Same as module A, but the last match makes every other match inconsitent, -- because after converting to an if then else the last match may become -- impossible to reach. -- So no alterations will be made, except for some indentation differences. f (C {x = myx}) ([],0) x | x < 0 = myx f A (lst,0) x | x == 1 = head lst -- disjoint from others f (C a b) r@([] ,0) x | x > 0 = snd r f (B 0) (a,b) x | x == 2 = b f ((B 0)) (a,c) x | x == 3 = -c f _ _ _ = 0

module B where data X a = A | B a | C {x,y::a} -- Same as module A, but the last match makes every other match inconsitent, -- because after converting to an if then else the last match may become -- impossible to reach. -- So no alterations will be made, except for some indentation differences. f (C{x = myx}) ([], 0) x | x < 0 = myx f A (lst, 0) x | x == 1 = head lst f (C a b) r@([], 0) x | x > 0 = snd r f (B 0) (a, b) x | x == 2 = b f ((B 0)) (a, c) x | x == 3 = -c f _ _ _ = 0