Reputation: 61
I have a Haskell homework exercise to manually re-create findIndices
using recursion.
I've simplified the problem by hard-coding a cons 0 each time it finds an index that meets the criteria:
positions :: (a -> Bool) -> [a] ->[Integer]
positions p [] = []
positions p (x:xs)
| p x = 0 : positions p xs
| otherwise = positions p xs
But instead of outputting a 0 in each position of the output list, I want it to output the index but I cannot work out how to do this using a count variable.
I've tried to simplify this by just outputting the index to every item but can't work this out either so I've got:
pos :: [a] -> [Integer]
pos [] = []
pos (x:xs) = 0 : pos xs
which returns a 0 for every item in the list so [2,3,4,5] returns [0,0,0,0] as expected but I can't work out how to make it return [0,1,2,3]
I can make it count how many items are in the list but I can't work out how to put the count variable into the list.
pos1 :: [a] -> Integer
pos1 [] = 0
pos1 (x:xs) = let count = pos1 xs in count+1
Any help in "Haskell for Dummies" language would be much appreciated.
Upvotes: 2
Views: 163
Reputation: 116174
There are several ways to do that. I'll focus on a basic approach, even if better ones exist which exploit the library list functions.
You wrote you want a counter variable. So, start by defining a function which takes that counter (variable index
below) as an additional argument. Following the code you posted, we get:
positionsIndex :: Integer -> (a -> Bool) -> [a] -> [Integer]
positionsIndex index p [] = ...
positionsIndex index p (x:xs) = ...
After that, we can define the wanted function by providing the additional argument
positions :: (a -> Bool) -> [a] -> [Integer]
positions p xs = positionsIndex 0 p xs
The 0
above initializes the counter argument to the first position.
Now, you should finish positionsIndex
, by suitably adapting your already posted code. Note that you will have to pass the counter to each recursive call to positionsIndex
.
You can make positionsIndex
a local function adapting the following. Be careful to make all the related equations perfectly aligned.
positions :: (a -> Bool) -> [a] -> [Integer]
positions p xs = ...
where
positionsIndex :: Integer -> (a -> Bool) -> [a] -> [Integer]
positionsIndex index p [] = ...
positionsIndex index p (x:xs) = ...
Upvotes: 1