You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

是否存在适用于元组的zipWith类似函数?

实现元组版的zipWith:可选方案汇总

这个问题提得特别到位!确实,列表的zipWith能方便地逐元素应用二元函数,但元组因为其长度和类型固定的特性,base标准库里并没有直接提供tupleZipWith这类函数。不过咱们有不少实用的方案可以解决这个需求,下面逐一说明:

方案一:手动实现(针对特定长度元组)

如果你只需要处理固定长度的同类型元组(比如2元组、3元组),手动写函数是最直接的方式,完全不需要额外依赖。比如针对2元组:

tupleZipWith2 :: (a -> b -> c) -> (a, a) -> (b, b) -> (c, c)
tupleZipWith2 f (x1, x2) (y1, y2) = (f x1 y1, f x2 y2)

-- 调用示例:
-- tupleZipWith2 (+) (1,2) (3,4) → (4,6)

要是需要3元组,就依葫芦画瓢写个tupleZipWith3就行,逻辑完全一致,只是多处理一个元素。这种方式的优点是简单直观,编译效率也高,适合场景固定的情况。

方案二:用GHC泛型实现通用版本

如果想支持任意长度的同类型元组,可以借助Haskell的GHC.Generics泛型机制来实现一个通用的tupleZipWith。核心思路是把元组转换成泛型表示,递归地对每个元素应用函数,最后再转换回元组。

实现代码示例(需要启用几个GHC扩展):

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics

class TupleZipWith f where
  tupleZipWith' :: (a -> b -> c) -> f a -> f b -> f c

instance TupleZipWith U1 where
  tupleZipWith' _ U1 U1 = U1

instance TupleZipWith f => TupleZipWith (M1 i c f) where
  tupleZipWith' f (M1 x) (M1 y) = M1 (tupleZipWith' f x y)

instance (TupleZipWith f, TupleZipWith g) => TupleZipWith (f :*: g) where
  tupleZipWith' f (x1 :*: x2) (y1 :*: y2) = tupleZipWith' f x1 y1 :*: tupleZipWith' f x2 y2

instance TupleZipWith Par1 where
  tupleZipWith' f (Par1 x) (Par1 y) = Par1 (f x y)

tupleZipWith :: (Generic (t a), Generic (t b), Generic (t c), TupleZipWith (Rep (t a))) => (a -> b -> c) -> t a -> t b -> t c
tupleZipWith f x y = to (tupleZipWith' f (from x) (from y))

-- 调用示例:
-- tupleZipWith (+) (1,2,3) (4,5,6) → (5,7,9)
-- tupleZipWith (*) (10,20) (3,4) → (30,80)

这种方式一次实现就能支持所有同类型元组,但需要理解泛型的基本概念,代码也相对复杂一些。

方案三:借助第三方库

如果不想自己动手实现,有几个成熟的第三方库已经封装了这类功能:

  • tuple库:专门针对元组操作的库,提供了zipTuple2、zipTuple3等一系列函数,直接对应不同长度元组的zipWith需求,用法和手动实现的版本类似。
  • lens库:虽然主打镜头(Lens)功能,但可以通过each遍历器实现类似效果,比如(1,2) & each %~ (+) <$> (3,4),这种写法更偏向遍历更新,但能达到和tupleZipWith一致的结果。

内容的提问来源于stack exchange,提问作者duplode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:35:48