Session 22: Haskell introduction, cont'd

Today we complete Chapter 2 and we examine Section 3.2, Section 3.5, and Chapter 4 (except Section 4.4) from Hudak, Peterson, and Fasel's A Gentle Introduction to Haskell 98. Here are the specific examples covered in class.

-- user-defined type synonyms (Sec 2.3)

type Range = (Integer, Integer)

rangeLength :: Range -> Integer
rangeLength (a, b) = b - a + 1

-- strings (Sec 2.4.2)

substr :: String -> Range -> String
substr s (0, -1) = []
substr [] (a, b) = []
substr (x : xs) (0, b) = x : substr xs (0, b - 1)
substr (x : xs) (a, b) = substr xs (a - 1, b - 1)

sumFactorsTo n 0 = 0
sumFactorsTo n i = if n `mod` i == 0 then i + sumFactorsTo n (i - 1)
                                     else sumFactorsTo n (i - 1)

sumFactors :: Integer -> Integer
sumFactors n = sumFactorsTo n (n - 1)

-- infix functions (Sec 3.2)

(//) :: String -> Range -> String
[] // (a, b) = []
s // (0, -1) = []
(x : xs) // (0, b) = x : (xs // (0, b - 1))
(x : xs) // (a, b) = xs // (a - 1, b - 1)

-- error values (Sec 3.5) and patterns (Ch 4 intro)

substr2 :: String -> Range -> String
substr2 [] _ = error "range out of bounds"
substr2 s@(x : xs) (a, b) = if a == 0 then take (toInt b) s
                                      else substr2 xs (a - 1, b)

-- case expressions (Sec 4.3)

isPerfect :: Integer -> Bool
isPerfect n = case n of
                6  -> True
                28 -> True
                _  -> False

-- let expressions (Sec 4.5)

sumFactors :: Integer -> Integer
sumFactors n =
    let
        sumTo 0 = 0
        sumTo i = if n `mod` i == 0 then i + sumTo (i - 1)
                                             else sumTo (i - 1)
    in sumTo (n - 1)