Reputation: 2617
How do I access an element of a tuple in a list?
For example
func :: [(Int, Int, Int)] -> Int
func (x:xs) --here I want to access c of every tuple (a,b,c)
Upvotes: 2
Views: 845
Reputation: 19637
Note that you can simply nest pattern matches:
func :: [(Int, Int, Int)] -> Int
func ((a, b, c) : xs) = ... -- do something with c, and probably recurse on xs
func [] = ... -- don't forget the base case
Upvotes: 4
Reputation: 5373
You may be stuck with conversions. Average with an Int
is inherently messy if you use the wrong averaging. You need the fromIntegral
command to convert your Int to a float-type number like so ...
f x = sAll / l
where
f3 (_,_,x) = x
sAll = sum $ map (fromIntegral . f3) x
l = fromIntegral $ length x
{-
[prompt] f [(1,2,3), (2,4,6)]
4.5
[prompt]
-}
Was this the problem?
Upvotes: 1
Reputation: 54058
You can make a simple function to access the third element of a tuple then just use map
thrd :: (a, b, c) -> c
thrd (a, b, c) = c
func :: [(Int, Int, Int)] -> [Int]
func xs = map thrd xs
That will give you a list containing the third element of each tuple. I don't know what you want to do to it to convert it to a single Int
, though. Could you elaborate on your use case?
To get the average of these elements you're going to have to do some conversion. You can't divide Int
s, because Int
is not an instance of the Fractional
type class which defines (/)
. You could write an average function like
average :: Fractional a => [a] -> a
average xs = sum xs / fromIntegral (length xs)
But this would mean you would have to convert every single element coming out of map thrd xs
into a Fractional
. It'd be much more efficient to make a specialized averaging function for the Int
type defined as
averageInt :: Fractional a => [Int] -> a
averageInt xs = fromIntegral (sum xs) / fromIntegral (length xs)
The difference here is that you sum the list first, then convert that result to a Fractional
. You have to perform the sum either way, but this reduces the number of conversion you have to do from the number of elements in your list to 1 no matter the size of the list.
You can then use it as
averageThrd :: Fractional a => [(Int, Int, Int)] -> a
averageThrd xs = averageInt $ map thrd xs
Since Float
and Double
are both instances of Fractional
, you can convert to either of these types on demand with some in-line type annotations:
> averageThrd [(0, 0, 1), (0, 0, 2), (0, 0, 3)] :: Double
2.0
> averageThrd [(0, 0, 1), (0, 0, 2), (0, 0, 3)] :: Float
2.0
Upvotes: 4