From a475714e4dcf39a45a85b43dfa866b2f9d6c297b Mon Sep 17 00:00:00 2001 From: Jackson Machado Date: Thu, 1 Oct 2020 22:39:39 -0300 Subject: [PATCH 1/4] feat: solutions chapter 2 --- src/Chapter2.hs | 88 ++++++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index 812311d2..ff43a758 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -136,43 +136,43 @@ functions in GHCi and insert the corresponding resulting output below: List of booleans: >>> :t [True, False] - +[True, False] :: [Bool] String is a list of characters: >>> :t "some string" - +"some string" :: [Char] Empty list: >>> :t [] - +[] :: [a] Append two lists: >>> :t (++) - +(++) :: [a] -> [a] -> [a] Prepend an element at the beginning of a list: >>> :t (:) - +(:) :: a -> [a] -> [a] Reverse a list: >>> :t reverse - +reverse :: [a] -> [a] Take first N elements of a list: >>> :t take - +take :: Int -> [a] -> [a] Create list from N same elements: >>> :t replicate - +replicate :: Int -> a -> [a] Split a string by line breaks: >>> :t lines - +lines :: String -> [String] Join a list of strings with line breaks: >>> :t unlines - +unlines :: [String] -> String -} @@ -186,31 +186,31 @@ Evaluate the following expressions in GHCi and insert the answers. Try to guess first, what you will see. >>> [10, 2] ++ [3, 1, 5] - +[10,2,3,1,5] >>> [] ++ [1, 4] -- [] is an empty list - +[1,4] >>> 3 : [1, 2] - +[3,1,2] >>> 4 : 2 : [5, 10] -- prepend multiple elements - +[4,2,5,10] >>> [1 .. 10] -- list ranges - +[1,2,3,4,5,6,7,8,9,10] >>> [10 .. 1] - +[] >>> [10, 9 .. 1] -- backwards list with explicit step - +[10,9,8,7,6,5,4,3,2,1] >>> length [4, 10, 5] -- list length - +3 >>> replicate 5 True - +[True,True,True,True,True] >>> take 5 "Hello, World!" - +"Hello" >>> drop 5 "Hello, World!" - +", World!" >>> zip "abc" [1, 2, 3] -- convert two lists to a single list of pairs - +[('a',1),('b',2),('c',3)] >>> words "Hello Haskell World!" -- split the string into the list of words - +["Hello","Haskell","World!"] 👩‍🔬 Haskell has a lot of syntax sugar. In the case with lists, any @@ -336,7 +336,9 @@ from it! ghci> :l src/Chapter2.hs -} subList :: Int -> Int -> [a] -> [a] -subList = error "subList: Not implemented!" +subList from to list + | from < 0 || to < 0 || to < from = [] + | otherwise = drop from(take (to + 1) list) {- | =⚔️= Task 4 @@ -348,8 +350,8 @@ Implement a function that returns only the first half of a given list. >>> firstHalf "bca" "b" -} --- PUT THE FUNCTION TYPE IN HERE -firstHalf l = error "firstHalf: Not implemented!" +firstHalf :: [a] -> [a] +firstHalf l = take (div (length l) 2) l {- | @@ -500,7 +502,9 @@ True >>> isThird42 [42, 42, 0, 42] False -} -isThird42 = error "isThird42: Not implemented!" +isThird42:: [Int] -> Bool +isThird42 (_ : _ : 42 : _) = True +isThird42 _ = False {- | @@ -605,7 +609,8 @@ Implement a function that duplicates each element of the list -} duplicate :: [a] -> [a] -duplicate = error "duplicate: Not implemented!" +duplicate [] = [] +duplicate (x:xs) = x : x : duplicate xs {- | @@ -620,7 +625,10 @@ Write a function that takes elements of a list only on even positions. >>> takeEven [2, 1, 3, 5, 4] [2,3,4] -} -takeEven = error "takeEven: Not implemented!" +takeEven :: [Int] -> [Int] +takeEven [] = [] +takeEven [x] = [x] +takeEven (x : _ : xs) = x : takeEven xs {- | =🛡= Higher-order functions @@ -727,7 +735,7 @@ value of the element itself 🕯 HINT: Use combination of 'map' and 'replicate' -} smartReplicate :: [Int] -> [Int] -smartReplicate l = error "smartReplicate: Not implemented!" +smartReplicate l = concat (map (\x -> replicate x x) l) {- | =⚔️= Task 9 @@ -740,7 +748,8 @@ the list with only those lists that contain a passed element. 🕯 HINT: Use the 'elem' function to check whether an element belongs to a list -} -contains = error "contains: Not implemented!" +contains :: Int -> [[Int]] -> [[Int]] +contains x l = filter (elem x) l {- | @@ -780,7 +789,7 @@ Let's now try to eta-reduce some of the functions and ensure that we mastered the skill of eta-reducing. -} divideTenBy :: Int -> Int -divideTenBy x = div 10 x +divideTenBy x = div 10 x -- TODO: type ;) listElementsLessThan x l = filter (< x) l @@ -841,7 +850,13 @@ list. 🕯 HINT: Use the 'cycle' function -} -rotate = error "rotate: Not implemented!" +rotate :: Int -> [a] -> [a] +rotate n l + | n < 0 = [] + | null l = [] + | otherwise = + let len = length l + in take len (drop (mod n len) (cycle l)) {- | =💣= Task 12* @@ -857,7 +872,12 @@ and reverses it. function, but in this task, you need to implement it manually. No cheating! -} -rewind = error "rewind: Not Implemented!" +rewind :: [a] -> [a] +rewind = go [] + where + go :: [a] -> [a] -> [a] + go res [] = res + go res xs = foldl (flip (:)) res xs {- From f8d2ca4547c3d33d5ff368dc86fbcf6708a87eec Mon Sep 17 00:00:00 2001 From: Jackson Machado Date: Fri, 2 Oct 2020 12:11:19 -0300 Subject: [PATCH 2/4] fix: resolved eta-reduction --- src/Chapter2.hs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index ff43a758..db67a2e4 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -338,7 +338,7 @@ ghci> :l src/Chapter2.hs subList :: Int -> Int -> [a] -> [a] subList from to list | from < 0 || to < 0 || to < from = [] - | otherwise = drop from(take (to + 1) list) + | otherwise = drop from (take (to + 1) list) {- | =⚔️= Task 4 @@ -630,6 +630,13 @@ takeEven [] = [] takeEven [x] = [x] takeEven (x : _ : xs) = x : takeEven xs +takeEvenGo :: [Int] -> [Int] +takeEvenGo xs = go xs + where + go [] = [] + go (x:xs) + | x `mod` 2 == 1 = x : go xs + | otherwise = go xs {- | =🛡= Higher-order functions @@ -735,7 +742,7 @@ value of the element itself 🕯 HINT: Use combination of 'map' and 'replicate' -} smartReplicate :: [Int] -> [Int] -smartReplicate l = concat (map (\x -> replicate x x) l) +smartReplicate = concatMap (\x -> replicate x x) {- | =⚔️= Task 9 @@ -789,13 +796,15 @@ Let's now try to eta-reduce some of the functions and ensure that we mastered the skill of eta-reducing. -} divideTenBy :: Int -> Int -divideTenBy x = div 10 x +divideTenBy = div 10 -- TODO: type ;) -listElementsLessThan x l = filter (< x) l +listElementsLessThan :: Int -> [Int] -> [Int] +listElementsLessThan x = filter (< x) -- Can you eta-reduce this one??? -pairMul xs ys = zipWith (*) xs ys +pairMul :: [Int] -> [Int] -> [Int] +pairMul = zipWith (*) {- | =🛡= Lazy evaluation From ba58a96be497fea32f21e3626e425270013cc636 Mon Sep 17 00:00:00 2001 From: Jackson Machado Date: Fri, 2 Oct 2020 13:52:13 -0300 Subject: [PATCH 3/4] fix: change to use acc --- src/Chapter2.hs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index db67a2e4..441d37b2 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -631,12 +631,12 @@ takeEven [x] = [x] takeEven (x : _ : xs) = x : takeEven xs takeEvenGo :: [Int] -> [Int] -takeEvenGo xs = go xs +takeEvenGo xs = go 0 xs where - go [] = [] - go (x:xs) - | x `mod` 2 == 1 = x : go xs - | otherwise = go xs + go acc [] = [] + go acc (x:xs) + | even acc = x : go (acc +1) xs + | otherwise = go (acc +1) xs {- | =🛡= Higher-order functions From 447508cf13bfa850cb4489995230938ebf6faa27 Mon Sep 17 00:00:00 2001 From: Jackson Machado Date: Fri, 2 Oct 2020 21:44:27 -0300 Subject: [PATCH 4/4] fix: change to use rewind on one line --- src/Chapter2.hs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index 441d37b2..9fe08ea8 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -882,12 +882,7 @@ and reverses it. cheating! -} rewind :: [a] -> [a] -rewind = go [] - where - go :: [a] -> [a] -> [a] - go res [] = res - go res xs = foldl (flip (:)) res xs - +rewind = foldl (flip (:)) [] {- You did it! Now it is time to the open pull request with your changes