Haskell: как отобразить кортеж? - PullRequest
59 голосов
/ 15 марта 2012

В Хаскеле я могу легко сопоставить список:

map (\x -> 2*x) [1,2]

дает мне [2,4]. Есть ли какая-нибудь функция mapTuple, которая бы работала так?

mapTuple (\x -> 2*x) (1,2)

с результатом (2,4).

Ответы [ 13 ]

4 голосов
/ 16 ноября 2014

Пакет uniplate обеспечивает функцию нисходящий в модуле Data.Generics.Uniplate.Data .Эта функция будет применять эту функцию везде, где совпадают типы, поэтому ее можно применять к спискам, кортежам, либо к большинству других типов данных.Некоторые примеры:

descend (\x -> 2*x) (1,2) == (2,4)
descend (\x -> 2*x) (1,"test",Just 2) == (2,"test",Just 4)
descend (\x -> 2*x) (1,2,3,4,5) == (2,4,6,8,10)
descend (\x -> 2*x) [1,2,3,4,5] == [2,4,6,8,10]
4 голосов
/ 17 августа 2013

Я только что добавил пакет tuples-homogenous-h98 в Hackage, который решает эту проблему. Он добавляет newtype оболочки для кортежей и определяет для них экземпляры Functor, Applicative, Foldable и Traversable. Используя пакет, вы можете делать такие вещи, как:

untuple2 . fmap (2 *) . Tuple2 $ (1, 2)

или кортежи типа:

Tuple2 ((+ 1), (*2)) <*> Tuple2 (1, 10)
3 голосов
/ 15 марта 2012

Да, вы должны сделать:

map (\x -> (fst x *2, snd x *2)) [(1,2)]

fst захватывает первую запись данных в кортеже, а snd захватывает вторую;Итак, в строке кода написано: «Возьмите кортеж и верните другой кортеж, первый и второй элементы которого удваивают предыдущий».

...