将值映射转换为元组列表

时间:2019-07-23 19:19:04

标签: haskell

我正在尝试扩展函数toTuple,以使其占用[(d1, Just x), (d2, Just y), (d3, Just z)]并产生[(d1, d2, y), (d2, d3, z)]

import qualified Data.Function.Step.Discrete.Open as SF
import qualified Data.Map as Map

newtype DayMap a = DayMap (SF.SF Day (Maybe a))
  deriving stock (Show, Functor)

toTuple :: Map.Map Day (Maybe a) -> [(Day, Maybe Integer)]
toTuple a = produceList 
    where
      produceList = Map.toList (getDM td3)

getDM :: DayMap a -> Map.Map Day (Maybe a)
getDM (DayMap sf@(SF.SF m hi)) = m

td3 :: DayMap Integer
td3 = DayMap.insert (Just $ fromGregorian 2010 01 01) (Just $ fromGregorian 2012 01 01) 22 DayMap.empty

它当前产生的是:

> toTuple (getDM td3)
[(2010-01-01,Nothing),(2012-01-02,Just 22)]

即值Just 222010-01-012012-01-02之间有关,在此之前为空。

所以在这种情况下,我想以[(2010-01-01, 2012-01-02, (Just 22))]结尾。

我不清楚如何扩展我的toTuple函数。任何提示将不胜感激。

2 个答案:

答案 0 :(得分:3)

您可以使用以下方式处理此类列表:

toTuple :: [(a, b)] -> [(a, a, b)]
toTuple [] = []
toTuple xs@(_:xt) = zipWith f xs xt
    where f (x, _) (y, z) = (x, y, z)

因此,在此我们将一个空列表映射到一个空列表上。通过将列表(xs)的尾部(xt)压缩为列表,来处理非空列表,并将其作为“压缩功能” ff取“上一个”元组x的第一项和“下一个”元组(y, z),并构造一个三元组(x, y, z)

答案 1 :(得分:0)

@Willem Van Onsem 涵盖了所有内容。我让foldr的另一个版本非常不常规:

toTuple' :: [(a, b)] -> [(a, a, b)]
toTuple' xs = foldr (\_ _ -> zipWith f xs (tail xs)) [] xs
    where f (x, _) (y, z) = (x, y, z)

$> toTuple' [(1,2),(3,4),(5,6),(7,8)]

$> [(1,3,4),(3,5,6),(5,7,8)]