{-# htermination (sumMyInt :: (List MyInt) -> MyInt) #-} import qualified Prelude data MyBool = MyTrue | MyFalse data List a = Cons a (List a) | Nil data MyInt = Pos Nat | Neg Nat ; data Nat = Succ Nat | Zero ; data WHNF a = WHNF a ; enforceWHNF :: WHNF a -> b -> b; enforceWHNF (WHNF x) y = y; seq :: a -> b -> b; seq x y = enforceWHNF (WHNF x) y; dsEm :: (b -> a) -> b -> a; dsEm f x = seq x (f x); foldl' :: (a -> b -> a) -> a -> (List b) -> a; foldl' f a Nil = a; foldl' f a (Cons x xs) = dsEm (foldl' f) (f a x) xs; fromIntMyInt :: MyInt -> MyInt fromIntMyInt x = x; primMinusNat :: Nat -> Nat -> MyInt; primMinusNat Zero Zero = Pos Zero; primMinusNat Zero (Succ y) = Neg (Succ y); primMinusNat (Succ x) Zero = Pos (Succ x); primMinusNat (Succ x) (Succ y) = primMinusNat x y; primPlusNat :: Nat -> Nat -> Nat; primPlusNat Zero Zero = Zero; primPlusNat Zero (Succ y) = Succ y; primPlusNat (Succ x) Zero = Succ x; primPlusNat (Succ x) (Succ y) = Succ (Succ (primPlusNat x y)); primPlusInt :: MyInt -> MyInt -> MyInt; primPlusInt (Pos x) (Neg y) = primMinusNat x y; primPlusInt (Neg x) (Pos y) = primMinusNat y x; primPlusInt (Neg x) (Neg y) = Neg (primPlusNat x y); primPlusInt (Pos x) (Pos y) = Pos (primPlusNat x y); psMyInt :: MyInt -> MyInt -> MyInt psMyInt = primPlusInt; sumMyInt :: (List MyInt) -> MyInt sumMyInt = foldl' psMyInt (fromIntMyInt (Pos Zero));