module HaskellTypes2 where -- Determine whether the 3 arguments are mutually equal. Needs the user-chosen -- type to be an instance of Eq (supports "==") but otherwise polymorphic. eq3 :: Eq a => a -> a -> a -> Bool eq3 x y z = x==y && y==z -- Sorting algorithms just need Ord but otherwise polymorphic. insertionSort :: Ord a => [a] -> [a] insertionSort [] = [] insertionSort (x:xt) = insert x (insertionSort xt) where insert e [] = [e] insert e xs@(x:xt) | e <= x = e : xs | otherwise = x : insert e xt -- De-duplicating sorting uses both (==) and (<). Type sig just needs Ord. uniqInsertionSort :: Ord a => [a] -> [a] uniqInsertionSort [] = [] uniqInsertionSort (x:xt) = insert x (uniqInsertionSort xt) where insert e [] = [e] insert e xs@(x:xt) | e < x = e : xs | e == x = xs | otherwise = x : insert e xt data MyIntegerList = INil | ICons Integer MyIntegerList deriving Show data MyList a = Nil | Cons a (MyList a) deriving Show instance Eq MyIntegerList where INil == INil = True ICons x xs == ICons y ys = x==y && xs==ys _ == _ = False instance Eq a => Eq (MyList a) where -- The "Eq a =>" there means I need to use (==) on type a. -- Try omitting it to see what happens. Nil == Nil = True Cons x xs == Cons y ys = x==y && xs==ys -- "x==y" is when we need to assume Eq a. _ == _ = False epsilon :: (Ord a, Fractional a) => a epsilon = let -- [1, 0.5, 0.25, ...] halves = iterate (/ 2) 1 -- But only those that satisfy 1+e > 1. notTooSmall = takeWhile (\e -> 1 + e > 1) halves -- The last such e is the machine epsilon. in last notTooSmall epsilonDouble :: Double epsilonDouble = epsilon epsilonFloat :: Float epsilonFloat = epsilon