DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Roger has posted 34 posts at DZone. View Full User Profile

Real World Haskell Exercise - Ch 4

12.02.2009
| 2792 views |
  • submit to reddit
        // The first fold exercise from RWH, Chapter 4

{- Ex 1: Use a fold (choosing the appropriate fold will 
    make your code much simpler) to rewrite and improve upon 
    the asInt function from the section called “Explicit recursion”.
    
    Your function should behave as follows.
    
    ghci> asInt_fold "101"
    101
    ghci> asInt_fold "-31337"
    -31337
    ghci> asInt_fold "1798"
    1798
    
    Extend your function to handle the following kinds of exceptional conditions by calling error.
    
    ghci> asInt_fold ""
    0
    ghci> asInt_fold "-"
    0
    ghci> asInt_fold "-3"
    -3
    ghci> asInt_fold "2.7"
    *** Exception: Char.digitToInt: not a digit '.'
    ghci> asInt_fold "314159265358979323846"
    564616105916946374
-}
import Data.Char (digitToInt) -- we'll need ord
import Data.List (foldl')

-- powTen was originally a one-liner. I'm trying to guard against an int overflow,
-- but haven't yet found a way to successfully do so.
asInt_fold :: String -> Int
asInt_fold []  = error "String is empty"
asInt_fold "-" = error "dash is not a number"
asInt_fold ('-':xs) = (-1) * asInt_fold xs 
asInt_fold str = foldl' powTen 0 str
                         where maxis = maxBound::Int
                               powTen n ch 
                                  | n > (maxis) = error "overflow of int"
                                  | otherwise = n * 10 + (digitToInt ch)