Reputation: 274
How do I write a function that displays a given range in a list in Haskell? Say that I have the function:
dispRange l x y
that when given values:
dispRange [1,2,4,5,6,7] 0 3
displays all the elements from position 0 to 3, thus the list returned would be:
[1,2,4,5]
Upvotes: 2
Views: 2724
Reputation: 476584
We can use a combination of drop :: Int -> [a] -> [a]
and take :: Int -> [a] -> [a]
for this:
For a range i
to j
, we first drop i
elements, and then take j-i+1
elements (since both indices are inclusive, we thus need to add one).
For example:
dispRange :: [a] -> Int -> Int -> [a]
dispRange l i j = take (j-i+1) (drop i l)
We can guard against negative numbers and j
being less than i
with:
dispRange :: [a] -> Int -> Int -> Maybe [a]
dispRange l i j | i < 0 || j < i = Nothing
| otherwise = Just (take (j-i+1) (drop i l))
Upvotes: 6
Reputation: 892
dispRange
consumes a list: l
, the start:x
and the end:y
of a range inclusively. It returns the elements within that range if the range is not negative.
import Data.List ((\\))
dispRange :: Eq a => [a] -> Int -> Int -> [a]
dispRange l x y
| x <= y = (\\) <$> take (y + 1) <*> take x $ l
| otherwise = []
Upvotes: 2
Reputation: 3020
If you want to do it in a way that doesn't use built-in functions (for beginner's learning), you can break it into two stages:
Your code will look like this:
dispRange :: …
dispRange … … … = []
dispRange … … … = dispRange … … …
⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮
dispRange … … … = dispRange … … …
So, the questions are:
Now, you can write the type signature and the patterns on the left of the equal signs (remember that patterns above take priority over patterns below, so order them properly). Then, you can write the implementation of each case on the right of the equal sign.
If you have trouble, another way is to try making a function that does just stage one. Then, try making a function that does just stage two. Then, use those functions in your dispRange
function.
Upvotes: 1