From 6b5d934a5de4c002fbf9633f781e4b5d6670a23d Mon Sep 17 00:00:00 2001 From: Jan Sucan Date: Sun, 10 Dec 2023 15:48:00 +0100 Subject: 12_a_1: Add solution --- ch12/12_a_1.hs | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 ch12/12_a_1.hs (limited to 'ch12/12_a_1.hs') diff --git a/ch12/12_a_1.hs b/ch12/12_a_1.hs new file mode 100644 index 0000000..2ab71b1 --- /dev/null +++ b/ch12/12_a_1.hs @@ -0,0 +1,91 @@ +-- 1. Write a function that takes two arguments: a four-element tuple and an +-- integer. With an integer argument of zero, it should return the leftmost +-- element of the tuple. With an argument of one, it should return the next +-- element. And so on. What restrictions do you have to put on the types of +-- the arguments in order to write a function that typechecks correctly? +-- +-- 2. Write a similar function that takes a six-tuple as its first argument. +-- +-- 3. Try refactoring the two functions to share any common code you can +-- identify. How much shared code are you able to you find? + +-- In order for this function to typecheck correctly, all elements in the tuple +-- must have the same type, so the return value's type is always the same for +-- any value of the index. +get4 :: (a, a, a, a) -> Int -> Maybe a +get4 (a, _, _, _) 0 = Just a +get4 (_, b, _, _) 1 = Just b +get4 (_, _, c, _) 2 = Just c +get4 (_, _, _, d) 3 = Just d +get4 _ _ = Nothing + +get6 :: (a, a, a, a, a, a) -> Int -> Maybe a +get6 (a, _, _, _, _, _) 0 = Just a +get6 (_, b, _, _, _, _) 1 = Just b +get6 (_, _, c, _, _, _) 2 = Just c +get6 (_, _, _, d, _, _) 3 = Just d +get6 (_, _, _, _, e, _) 4 = Just e +get6 (_, _, _, _, _, f) 5 = Just f +get6 _ _ = Nothing + +-- Refactorring the two functions to share common code +get2 :: (a, a) -> Int -> Maybe a +get2 (a, _) 0 = Just a +get2 (_, b) 1 = Just b +get2 _ _ = Nothing + +-- The 'get6' function can be refactorred to make use of the 'get4' +-- function. However, this doesn't save much code. +refGet6 :: (a, a, a, a, a, a) -> Int -> Maybe a +refGet6 t i = maybe gy (\j -> Just j) gx + where (a, b, c, d, e, f) = t + x = (a, b, c, d) + y = (e, f) + gx = get4 x i + gy = get2 y (i - 4) + + +-- ghci> :l 12_a_1.hs +-- [1 of 1] Compiling Main ( 12_a_1.hs, interpreted ) +-- Ok, one module loaded. + +-- ghci> get4 ('1', '2', '3', '4') 0 +-- Just '1' +-- ghci> get4 ('1', '2', '3', '4') 1 +-- Just '2' +-- ghci> get4 ('1', '2', '3', '4') 2 +-- Just '3' +-- ghci> get4 ('1', '2', '3', '4') 3 +-- Just '4' +-- ghci> get4 ('1', '2', '3', '4') 4 +-- Nothing + +-- ghci> get6 ('1', '2', '3', '4', '5', '6') 0 +-- Just '1' +-- ghci> get6 ('1', '2', '3', '4', '5', '6') 1 +-- Just '2' +-- ghci> get6 ('1', '2', '3', '4', '5', '6') 2 +-- Just '3' +-- ghci> get6 ('1', '2', '3', '4', '5', '6') 3 +-- Just '4' +-- ghci> get6 ('1', '2', '3', '4', '5', '6') 4 +-- Just '5' +-- ghci> get6 ('1', '2', '3', '4', '5', '6') 5 +-- Just '6' +-- ghci> get6 ('1', '2', '3', '4', '5', '6') 6 +-- Nothing + +-- ghci> refGet6 ('1', '2', '3', '4', '5', '6') 0 +-- Just '1' +-- ghci> refGet6 ('1', '2', '3', '4', '5', '6') 1 +-- Just '2' +-- ghci> refGet6 ('1', '2', '3', '4', '5', '6') 2 +-- Just '3' +-- ghci> refGet6 ('1', '2', '3', '4', '5', '6') 3 +-- Just '4' +-- ghci> refGet6 ('1', '2', '3', '4', '5', '6') 4 +-- Just '5' +-- ghci> refGet6 ('1', '2', '3', '4', '5', '6') 5 +-- Just '6' +-- ghci> refGet6 ('1', '2', '3', '4', '5', '6') 6 +-- Nothing -- cgit v1.2.3