Before you start implementing the functions in this exercise, you need to understand how lists work in Haskell. Haskell lists are written like a list in math. The Haskell list:
is basically equivalent to the list:
One of the most important things about lists is that you can access the list as a whole and you can access the elements inside the list. One thing you can do is you can concatenate lists using the ++
function:
You can find the length of the list using the length
function:
These are the different ways you can access the elements of the list and the sublists in the list:
head
takes a list and returns the first element of the list
tail
takes a list and returns the same list except the first element of the list
init
takes a list and returns the same list except the last element of the list
last
takes a list and returns the same list except the last element of the list
Using these functions you can traverse a list using the head-tail recipe. For example, if you want to add 1 to each of the elements of the array:
Let's dissect this function one by one, for the first line you can see the type signature [Int]->[Int]
meaning addone
accepts a list of Int
s and returns a list of Int
s. Any type a
surrounded by brackets is a list of a
s ([a]
is a list of a
's, [Char]
is a list of Chars
, [[Int]]
is a list of [Int]
s or a list of list of Int
s).
In the second line were binding the list we are passing to l
.
The third line refers to the base case, this happens when the list is empty. When the list is empty we return []
which refers to an empty list.
And finally the last line refers to the general case. Here we are see the subexpression [(head l) + 1]
which is a list containing one element namely, the first element of the list plus 1. And then we are concatenating this one element list to the result of the call addone (tail l)
which is a recursive call to the rest of add one to the tail
of l (or the rest of l
). Assuming addone
works perfectly, the recursive call addone (tail l)
will return the tail of the l
but the elements are added with one. By concatenating [(head l) + 1]
with the result of this recursive call, we complete the desired result.
my_map
, my_filter
, and my_foldl
and my_foldr
, my_zip
my_map :: (a -> b) -> [a] -> [b]
- The map
function accepts a function and a list (with elements of type A
) . It returns the list (with elements of type B
): . The new list map
produces is a list which is the image of l
from the function f
.my_filter :: (a -> Bool) -> [a] -> [a]
- The filter
function accepts a predicate and a list . filter
returns a new list such that the contents satisfy is true, retaining the order it appears in .my_foldl :: (a -> a -> a) -> a -> [a] -> a
- The foldl
function accepts a function , a list and an initial value . The foldl
function returns the value .my_foldr :: (a -> a -> a) -> a -> [a] -> a
- The foldr
function accepts a function , a list and an initial value . The foldr
function returns the value .my_zip :: (a -> b -> c) -> [a] -> [b] -> [c]
- THe zip
function accepts a function and two lists , and returns a new list, Given a list of numbers, return the sum of the squares of the numbers
Given three lists, a list of first names, A, a list of middle names B, and a list of surnames C. Return a list of whole name strings (list of chars) ([firstname] [middle initial]. [lastname]
) where the length of the string (including spaces and period) is an even number. Example
("Foo S. Abcd" is filtered out because it has 11 characters)