Exercises part 1
In these exercises you are going to implement several recursive functions. Make sure to use tail recursion whenever possible and quickly verify the correct behavior of all functions at the REPL.
-
Implement functions
anyListandallList, which returnTrueif any element (or all elements in case ofallList) in a list fulfills the given predicate:anyList : (a -> Bool) -> List a -> Bool allList : (a -> Bool) -> List a -> Bool -
Implement function
findList, which returns the first value (if any) fulfilling the given predicate:findList : (a -> Bool) -> List a -> Maybe a -
Implement function
collectList, which returns the first value (if any), for which the given function returns aJust:collectList : (a -> Maybe b) -> List a -> Maybe bImplement
lookupListin terms ofcollectList:lookupList : Eq a => a -> List (a,b) -> Maybe b -
For functions like
maporfilter, which must loop over a list without affecting the order of elements, it is harder to write a tail recursive implementation. The safest way to do so is by using aSnocList(a reverse kind of list that's built from head to tail instead of from tail to head) to accumulate intermediate results. Its two constructors areLinand(:<)(called the snoc operator). ModuleData.SnocListexports two tail recursive operators called fish and chips ((<><)and(<>>)) for going fromSnocListtoListand vice versa. Have a look at the types of all new data constructors and operators before continuing with the exercise.Implement a tail recursive version of
mapforListby using aSnocListto reassemble the mapped list. Use then the chips operator with aNilargument to in the end convert theSnocListback to aList.mapTR : (a -> b) -> List a -> List b -
Implement a tail recursive version of
filter, which only keeps those values in a list, which fulfill the given predicate. Use the same technique as described in exercise 4.filterTR : (a -> Bool) -> List a -> List a -
Implement a tail recursive version of
mapMaybe, which only keeps those values in a list, for which the given function argument returns aJust:mapMaybeTR : (a -> Maybe b) -> List a -> List bImplement
catMaybesTRin terms ofmapMaybeTR:catMaybesTR : List (Maybe a) -> List a -
Implement a tail recursive version of list concatenation:
concatTR : List a -> List a -> List a -
Implement tail recursive versions of bind and
joinforList:bindTR : List a -> (a -> List b) -> List b joinTR : List (List a) -> List a