asInt_either
Real World Haskell, Exercise 4, p. 98:
The asInt_fold
function uses error
, so its callers cannot handle errors. Rewrite it to fix this problem.
-- file: ch04/IntParse.hs import Data.Char (digitToInt) asInt :: String -> Int asInt ('-':xs) = -1 * asInt xs asInt xs = foldl step 0 xs where step acc x = acc * 10 + safeDigitToInt x safeDigitToInt :: Char -> Int safeDigitToInt x = if x >= '0' && x <= '9' then digitToInt x else error "Non-digit" asInt_either :: String -> Ei asInt_either xs = if onlyHasDigits xs then Main.Right (asInt xs) else Main.Left ("non-digit '" ++ ((firstNonDigit xs) : "'")) onlyHasDigits :: String -> Bool onlyHasDigits [] = True onlyHasDigits (x:xs) = if x >= '0' && x <= '9' then onlyHasDigits xs else False firstNonDigit :: String -> Char firstNonDigit [] = '\0' firstNonDigit (x:xs) = if x <= '0' || x >= '9' then x else firstNonDigit xs data Ei = Right Int | Left String deriving (Show)
Doubtless this could be much mproved by someone who knows what they’re doing.
January 21st, 2009 at 2:12 AM
It seems better for firstNonDigit [] to throw an error, given that you never expect it to be called, and silently returning a null character will probably cause much confusion if it ever actually happens.
January 21st, 2009 at 9:42 AM
Actually, I could just delete it, I think.
One thing that bothers me, probably just because I don’t know enough Haskell yet, is how to mark a function “private”. That is, I want to only allow the function to be called from within the same source file. Of course, I could just inline the function, but this is hard enough to read as is.
January 21st, 2009 at 5:38 PM
I’m not a Haskell expert, but it seems that modules export everything by default, unless you explicitly list which symbols you wish to export. Personally I prefer the approach taken by Mercury, in which each module has an interface section and an implementation section, much like a C header file followed by its implementation. I find that more elegant than Java, in which public and private methods and method bodies are all intertwingled, and getting a high-level overview of the class is easier from the generated API docs.
February 5th, 2009 at 4:30 PM
The Java approach, though, has the strengths of its weaknesses: you can easily see, looking at a given method or whatever, whether it’s public or private. Keeping that information near the top is good for a module-level overview, but easy to get wrong at the level of writing methods.