将元组转换为haskell中的数据类型

时间:2014-12-14 00:59:36

标签: haskell

我遇到了将包含多个元组的列表转换为数据类型

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

我的元组列表如下所示:

[(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])]),...]

基本上我的列表看起来像[(Integer, [(Integer, [Integer])])]

实施例

如果我从列表(1, [(2, [3,4,5])中取出第一个元组,那么我的预期输出是:

一个SensorValue对象:

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

我知道如何使用fst获取第一个元组但是如何进入第二个元组?

2 个答案:

答案 0 :(得分:2)

您可以在此处使用模式匹配。你的功能看起来像这样:

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

您仍需要指定处理其他情况的条件,例如如果构成外元组的第二个元素的列表为空,会发生什么?

答案 1 :(得分:2)

列出理解或做语法使这很好 - 假设你理解它们!

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
    ]

根据您想要做的事情,您甚至可以考虑在结果列表的每个元素中仅存储一个传感器值。像这样(上面的命名方案有一个变体,只是为了好玩):

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