letsjak
letsjak

Reputation: 359

convert tuples to a datatype in haskell

I am having issues to convert a list with multiple tuples into a datatype

data SensorValue = SensorValue {a:: Integer, b:: Integer, c:: [Integer]} deriving (Show)

my list with tuples looks like this:

[(1, [(2, [3,4,5]), (2, [2,3,1]), (3, [2,3,7])]), (2, [(1, [4,4,1]), (2, [2,3,1]), (3, [9,0,3])]),...]

so basically my list looks like [(Integer, [(Integer, [Integer])])]

Example

If I take the first tuple from my list (1, [(2, [3,4,5]) then my expected output is:

a SensorValue object with :

a = 1       -- first element of the first tuple
b = 2       -- first element of the second tuple
c = [3,4,5] -- second element of the second tuple

I know how to get to the first tuple with fst but how do I get to the second tuple?

Upvotes: 1

Views: 246

Answers (2)

shree.pat18
shree.pat18

Reputation: 21757

You can use pattern matching here. Your function would look something like this:

f :: (Integer,[(Integer,[Integer])]) -> [SensorValue]
f (x,((y,z):zs)) = SensorValue x y z : f (x,zs) -- First element same for all
f(x,[]) = []

Demo

You would still need to specify the conditions to handle other cases e.g. What happens if the list that forms the second element of the outer tuple is empty?

Upvotes: 2

Daniel Wagner
Daniel Wagner

Reputation: 152682

List comprehensions or do syntax make this quite nice -- assuming you understand them!

doSyntax, listComprehensions :: [(Integer, [(Integer, [Integer])])] -> [SensorValue]

doSyntax sensorPoints = do
    (a, pointsAtA ) <- sensorPoints
    (b, valuesAtAB) <- pointsAtA
    return (SensorValue a b valuesAtAB)

listComprehensions sensorPoints =
    [ SensorValue a b valuesAtAB
    | (a, pointsAtA ) <- sensorPoints
    , (b, valuesAtAB) <- pointsAtA
    ]

Depending on just what you want to do, you might even consider storing just one sensor value in each element of the result list. Like this (with a variant on the naming scheme above, just for fun):

data SensorValue = SensorValue { a, b, val :: Integer }
fromRawData abvalM =
    [ SensorValue a b val
    | (a, bvalM) <- abvalM
    , (b,  valM) <-  bvalM
    , val        <-   valM
    ]

Upvotes: 2

Related Questions