Emma Lee
Emma Lee

Reputation: 143

Finding the length of a list at any given index n within an [[Int]] list

My question might be very simple and elementary, but I feel like there is one crucial thing I've missed so far.

My goal is to compute the length of a list within an [[Int]] list, at any given index.

For instance, listLength [[1,2],[1,2,3],[1,2,3,4]] 3 should result in 4. My function goes as follows

listLength :: [[Int]] -> Int -> Int 
listLength (x:[xs]:[[xxs]]) n = length ((x:[xs]:[[xxs]]) !! n) 

it compiles too, but whenever I call it with a parameter similar to the one above I get a Non-exhaustive patterns in function exception.

What I think I'm missing here is the part where one has to define a suitable pattern for a list with 1) variable length within the [[Int]] list, however, with also 2) variable length within the [Int] lists which the [[Int]] list is composed of.

I've tried x:[xs] for simulating 2), and [xs]:[[xxs]] for simulating 1). However, I still receive the error that there is no pattern to be matched with.

How could I simulate the preceeding narrative? Any help would be super super appreciated.

Upvotes: 1

Views: 72

Answers (1)

chi
chi

Reputation: 116139

The pattern you seek is... xss:

listLength :: [[Int]] -> Int -> Int 
listLength xss n = length (xss !! n) 

Note that this uses indices starting from 0, as usual. If you need the indices to start from 1, use length (xss !! (n-1)) instead.

It is a fairly common error to use a pattern which is too complex only because one feels that working on lists-of-lists requires some special care with respect to only lists. However, that is a red herring. Note the types:

xss :: [[Int]]
n :: Int
xss !! n :: [Int]   -- since that's the element type of [[Int]]
length (xss !! n) :: Int

Also, there is no need to make a special case for the empty/non-empty list: length already handles all cases.

Upvotes: 4

Related Questions