Reputation: 2967
I'm iterating through a list of [Char], I'm wondering the best way to perform the iteration.
This function calls itself recursively and passes back to itself a counter that gets decreased per iteration.
Its just for illustrative purposes, so always return True for each Char:
text = ["abcsdsdsdsd"]
exampleFunction :: Int -> String -> [Bool]
exampleFunction textlen text
| textlen >= 0 = True : exampleFunction (textlen - 1) text
| otherwise = []
Using 'textlen' as a counter seems rather imperative, is this the best way and/or the most Haskell-like to implement this?
Upvotes: 0
Views: 233
Reputation: 531055
The counter isn't necessary. The length of the list isn't particularly important; you just use it to determine if the list is non-empty (textlen >= 0
) or not. You can do the same thing by pattern matching on the argument itself.
exampleFunction :: [String] -> [Bool]
exampleFunction (x:xs) = True : exampleFunction xs
exampleFunction [] = []
As pointed out in a comment, this particular recursion scheme is abstracted out as the map
function:
exampleFunction :: [String] -> [Bool]
exampleFunction xs = map (const True) xs
where const True
returns a function that returns True
no matter what its argument is. (const True
can also be written as an explicit lambda expression (\_ -> True
). map
applies this function to each element of xs
and combines the results into a new list.
Other recursion schemes capture different styles of recursion (filter
, foldr
, etc), so while it is always possible to write an explicit recursive function to accomplish your task, you can often avoid it by using the appropriate higher order function.
I'm abusing the term recursion scheme a bit; map
and filter
can be thought of as special cases of foldr
, which is an example of a general recursion scheme known as a catamorphism.
Upvotes: 2