Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
pp:l03 [2021/03/21 19:00]
pdmatei
pp:l03 [2022/03/20 15:13] (current)
bogdan.deac
Line 7: Line 7:
  
 ==== Lambdas ==== ==== Lambdas ====
-46. Functions can be passed as arguments just like any other value value. Also, functions can be returned as parameter. In order to do so, it is convenient to define functions without naming them. This is done using **lambda**'​s. For a more detailed discussion regarding lambdas, see the lecture. The following definitions are equivalent:+Functions can be passed as arguments just like any other value value. Also, functions can be returned as parameter. In order to do so, it is convenient to define functions without naming them. This is done using **lambda**'​s. For a more detailed discussion regarding lambdas, see the lecture. The following definitions are equivalent:
  
 <code haskell> <code haskell>
Line 16: Line 16:
 </​code>​ </​code>​
  
-===== 1. String processing =====+===== 3.1. String processing =====
  
 The following is an input test. You can add more examples to it: The following is an input test. You can add more examples to it:
Line 25: Line 25:
 Use ''​map'',​ ''​foldr''/''​foldl'',​ instead of recursive functions. Wherever possible, use functional composition and closures. Use ''​map'',​ ''​foldr''/''​foldl'',​ instead of recursive functions. Wherever possible, use functional composition and closures.
  
-1.1. Remove uppercases from emails. (Do **not** use recursion). To be able to use character functions from the library, add ''​import Data.Char''​ at the beginning of the program. Use the Internet to find the appropriate character function.+3.1.1. Remove uppercases from emails. (Do **not** use recursion). To be able to use character functions from the library, add ''​import Data.Char''​ at the beginning of the program. Use the Internet to find the appropriate character function.
  
 <code haskell> <code haskell>
Line 32: Line 32:
 </​code>​ </​code>​
  
-1.2. Write a function which removes emails longer than a given size. Write the function as a **functional closure**. Use anonymous functions in your implementation,​ then think about how you can replace them by a functional composition of more basic functions. **Hint:** Write your code in steps. Start with the basic idea, then think about how you can write it better and cleaner.+3.1.2. Write a function which removes emails longer than a given size. Write the function as a **functional closure**. Use anonymous functions in your implementation,​ then think about how you can replace them by a functional composition of more basic functions. **Hint:** Write your code in steps. Start with the basic idea, then think about how you can write it better and cleaner.
  
 <code haskell> <code haskell>
Line 39: Line 39:
 </​code>​ </​code>​
  
-1.3. Count the number of emails longer than 12 characters. Use a fold, anonymous functions and functional composition.+3.1.3. Count the number of emails longer than 12 characters. Use a fold, anonymous functions and functional composition.
 <code haskell> <code haskell>
 howmany = howmany =
 </​code>​ </​code>​
  
-1.4. Split the list between first names and email domains. What ingredients (auxiliary functions) are necessary? Use either a fold or a tail-recursive function in your implementation.+3.1.4. Split the list between first names and email domains. What ingredients (auxiliary functions) are necessary? Use either a fold or a tail-recursive function in your implementation.
 <code haskell> <code haskell>
 names_emails :: [String] -> [[String]] names_emails :: [String] -> [[String]]
Line 50: Line 50:
 </​code>​ </​code>​
  
-1.5. Identify the list of the employed domain names (e.g. ''​gmail.com''​). Remove duplicates. Use no recursion and no additional. Prelude ​function apart from ''​head''​ and ''​tail''​. **Hint** think about the sequence of basic operations you want to perform and assemble them using functional composition.+3.1.5. Identify the list of the employed domain names (e.g. ''​gmail.com''​). Remove duplicates. Use no recursion and no additional ​prelude ​function apart from ''​head''​ and ''​tail''​. **Hint** think about the sequence of basic operations you want to perform and assemble them using functional composition.
 <code haskell> <code haskell>
 domains :: [String] -> [String] domains :: [String] -> [String]
Line 56: Line 56:
 </​code>​ </​code>​
  
-(!) 1.6. In some previous exercise you have, most likely, implemented a split function using ''​foldr''​. Implement one with ''​foldl''​. **Hint:** use an example together with the ''​foldl''​ implementation to figure out what the accumulator should do.+(!) 3.1.6. In some previous exercise you have, most likely, implemented a split function using ''​foldr''​. Implement one with ''​foldl''​. **Hint:** use an example together with the ''​foldl''​ implementation to figure out what the accumulator should do.
  
 <code haskell> <code haskell>
Line 63: Line 63:
 </​code>​ </​code>​
  
-1.7. Write a function which extracts the domains from emails, without the dot part. (e.g. ''​gmail''​). Generalise the previous function ''​splitl''​ to ''​splitBy::​ Char -> String -> [String]'',​ and use it each time necessary, in your implementation. **Hint**: Wherever you want to mix pattern matching with guards, start with the patterns first.+3.1.7. Write a function which extracts the domains from emails, without the dot part. (e.g. ''​gmail''​). Generalise the previous function ''​splitl''​ to ''​splitBy::​ Char -> String -> [String]'',​ and use it each time necessary, in your implementation. **Hint**: Wherever you want to mix pattern matching with guards, start with the patterns first.
  
 <code haskell> <code haskell>
Line 70: Line 70:
 </​code>​ </​code>​
  
-===== 2. A predicate-based implementation for sets ===== +===== 3.2. A predicate-based implementation for sets ===== 
-2.1. Consider **sets** represented as characteristic functions with signature ''​s :: Integer -> Bool'',​ where ''​s x''​ is true if ''​x''​ a member in the set. Examples:+3.2.1. Consider **sets** represented as characteristic functions with signature ''​s :: Integer -> Bool'',​ where ''​s x''​ is true if ''​x''​ a member in the set. Examples:
 <code haskell> <code haskell>
 s1 1 = True s1 1 = True
Line 77: Line 77:
 s1 _ = False s1 _ = False
  
-s2 x = x `mod2 == True+s2 x = mod 2 == 0
  
 s3 _ = False s3 _ = False
Line 88: Line 88:
 </​code>​ </​code>​
  
-2.2. Define the set $math[\{2^n \mid n\in\mathbb{N}\}]. ​+3.2.2. Define the set $math[\{2^n \mid n\in\mathbb{N}\}]. ​
  
-2.3. Define the set of natural numbers.+3.2.3. Define the set of natural numbers.
  
-2.4. Implement the intersection of two sets. Use lambdas.+3.2.4. Implement the intersection of two sets. Use lambdas.
 <code haskell> <code haskell>
 intersection :: (Integer -> Bool) -> (Integer -> Bool) -> (Integer -> Bool) intersection :: (Integer -> Bool) -> (Integer -> Bool) -> (Integer -> Bool)
 </​code>​ </​code>​
  
-2.5. Write intersection in another way, (without using lambdas). ​+3.2.5. Write intersection in another way, (without using lambdas). ​
 <code haskell> <code haskell>
 intersection'​ :: (Integer -> Bool) -> (Integer -> Bool) -> Integer -> Bool intersection'​ :: (Integer -> Bool) -> (Integer -> Bool) -> Integer -> Bool
 </​code>​ </​code>​
  
-2.6. Write a function which takes a list of integers, and returns the set which contains them.+3.2.6. Write a function which takes a list of integers, and returns the set which contains them.
 <code haskell> <code haskell>
 toSet :: [Integer] -> (Integer -> Bool) toSet :: [Integer] -> (Integer -> Bool)
 </​code>​ </​code>​
  
-2.7. Implement a function which takes a list of sets and computes their intersection.+3.2.7. Implement a function which takes a list of sets and computes their intersection.
  
 <code haskell> <code haskell>
Line 113: Line 113:
 </​code>​ </​code>​
  
 +===== 3.3. Brain twisters =====
 +3.3.1. Implement ''​map''​ using ''​foldl''​ and ''​foldr''​
  
 +<code haskell>
 +mapr :: (a -> b) -> [a] -> [b]
 +mapl :: (a -> b) -> [a] -> [b]
 +</​code>​
  
 +3.3.2. Implement ''​filter''​ using ''​foldl''​ and ''​foldr''​
 +
 +<code haskell>
 +filterl :: (a -> Bool) -> [a] -> [a]
 +filterr :: (a -> Bool) -> [a] -> [a]
 +</​code>​
 +
 +3.3.3. Implement ''​foldl''​ using ''​foldr''​
 +<code haskell>
 +myfoldl :: (a -> b -> a) -> a -> [b] -> a
 +</​code>​
 +3.3.4. Implement ''​bubbleSort''​. It must use at least one fold
 + <​code haskell>
 +bubbleSort :: [Integer] -> [Integer]
 +</​code>​