Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Choosing data from a list of tuples in Haskell

I have a list of tuples of tuples of type :: [((a, b), (a, b), (a, b))], in Haskell.

For some context, the 3 points (a, b) represent a (time, value) pair on a U shaped curve with the first point, at the initial time t1 having a maximum value on the curve x1, the third point with a greater time t3=t1+dt and a value x3

I would like find the range for the widest U in the list [((t1, x1), (t2, x2), (t3, x3))] by taking the tuple with the maximum t3 - t1, and then returning the value x2 - x1.

The only way I can think to do it is to first map each tuple in the list to t3 - t1, find its index, then calculate x2 - x1 for that index in the original list. Is there a more elegant way to do this?

findMaxTime :: [((a, b), (a, b), (a, b))] -> Int
findMaxTime list = elemIndex (==min) $ map (\(x, y, z) -> fst z - fst x)
                       where min = minimum $ map (\(x, y, z) -> fst z - fst x)

findMaxVal :: [((a, b), (a, b), (a, b))] -> b
findMaxVal list = list !! findMaxTime list

Any help would be appreciated.

Thanks, Ash

like image 211
Ash Avatar asked Aug 11 '10 20:08

Ash


People also ask

How do I turn a list into a tuple Haskell?

In a general way, you can't. Each size of tuple is a distinct type, whereas lists of any length are a single type. Thus, there's no good way to write a function that takes a list and returns a tuple of the same length--it wouldn't have a well-defined return type.

How do you get the first N elements of a list in Haskell?

There is a function in Haskell that takes first n elements of user-supplied list, named take . The syntax is: function-name arg1 arg2 . So, take takes first 1000 elements from an infinite list of numbers from 0 to infinity.

How do you get the second element in a tuple Haskell?

2. snd. This tuple function is used to get the second element from the tuple values or group. We can use this function before the tuple and it will return us the second element as the result in Haskell.


1 Answers

You can use maximumBy with comparing:

module Main where

import Data.Ord (comparing)
import Data.List (maximumBy)

findMaxVal :: (Num a, Ord a, Num b, Ord b) => [((a, b), (a, b), (a, b))] -> b
findMaxVal = xWidth . maximumBy (comparing tWidth)
  where
    xWidth ((_, x1), (_, x2), _) = x2 - x1
    tWidth ((t1, _), _, (t3, _)) = t3 - t1
like image 75
Travis Brown Avatar answered Oct 19 '22 10:10

Travis Brown