aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--ch04/4_b_3.hs58
2 files changed, 59 insertions, 1 deletions
diff --git a/README.md b/README.md
index 238d718..d11318d 100644
--- a/README.md
+++ b/README.md
@@ -74,7 +74,7 @@ more visible in the list the first exercise of a group is in bold italics.
| 4_a_4 | yes | | |
| **_4_b_1_** | yes, in 4_b_2 | 97 | |
| 4_b_2 | yes | 98 | |
-| 4_b_3 | | | |
+| 4_b_3 | yes | | |
| 4_b_4 | | | |
| 4_b_5 | | | |
| 4_b_6 | | | |
diff --git a/ch04/4_b_3.hs b/ch04/4_b_3.hs
new file mode 100644
index 0000000..9185f4e
--- /dev/null
+++ b/ch04/4_b_3.hs
@@ -0,0 +1,58 @@
+-- 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
+
+-- The assignment is ambiguous. It tells us we should call error, but the
+-- examples show only one example of an error situation (for input "2.7"). This
+-- error is already caught and reported by the digitToInt function, producing
+-- the same error as shown in the examples, so no work from us is needed to make
+-- the function to behave as required.
+--
+-- However, the next exercise replaces the call to error by returning Either.
+--
+-- Let's make the function to behave as specified in assignment of this
+-- exercise, calling error producing the same error output as shown in the next
+-- exercise, thus preparing the code for that exercise.
+--
+-- ghci> asInt_fold "2.7"
+-- *** Exception: non-digit '.'
+
+import Data.Char (digitToInt, isDigit)
+
+asInt_fold :: String -> Int
+asInt_fold "" = 0
+asInt_fold "-" = 0
+asInt_fold ('-':xs) = -1 * (asInt_fold' xs)
+asInt_fold xs = asInt_fold' xs
+
+asInt_fold' :: String -> Int
+asInt_fold' xs = foldl nextDigit 0 xs
+ where nextDigit acc digit
+ | not (isDigit digit) = error ("non-digit '" ++ [digit] ++ "'")
+ | otherwise = (acc * 10) + (digitToInt digit)
+
+-- ghci> :l 4_b_3.hs
+-- [1 of 1] Compiling Main ( 4_b_3.hs, interpreted )
+-- Ok, one module loaded.
+-- ghci> asInt_fold ""
+-- 0
+-- ghci> asInt_fold "-"
+-- 0
+-- ghci> asInt_fold "-3"
+-- -3
+-- ghci> asInt_fold "2.7"
+-- *** Exception: non-digit '.'
+-- CallStack (from HasCallStack):
+-- error, called at 4_b_3.hs:41:35 in main:Main
+-- ghci> asInt_fold "314159265358979323846"
+-- 564616105916946374