“为什么没有?”;“一般”;Haskell中元组的访问器函数?

“为什么没有?”;“一般”;Haskell中元组的访问器函数?,haskell,typeclass,Haskell,Typeclass,我知道有fst和snd,但是为什么使用类型类的访问器函数没有“通用”定义呢?我会建议像这样的东西 class Get1 p a | p -> a where get1 :: p -> a instance Get1 (a,b) a where get1 (x,_) = x instance Get1 (a,b,c) a where get1 (x,_,_) = x class Get2 p a | p -> a where get2 :: p -&g

我知道有
fst
snd
,但是为什么使用类型类的访问器函数没有“通用”定义呢?我会建议像这样的东西

class Get1 p a | p -> a where
  get1 :: p -> a 

instance Get1 (a,b) a where
  get1 (x,_) = x 

instance Get1 (a,b,c) a where
  get1 (x,_,_) = x 

class Get2 p a | p -> a where
  get2 :: p -> a 

instance Get2 (a,b) b where
  get2 (_,x) = x 

instance Get2 (a,b,c) b where
  get2 (_,x,_) = x 

当然,您需要一些语言扩展来实现这一点,但这不是更方便吗?尤其是您可以为自己的类型添加实例。

这样的类型类只提供编码(语法)便利,我不知道如何在它们的基础上构建通用的元组类型工具。如果您正在寻找元组泛化,请查看Reddit

还请注意,对于普通结构,最好定义自己的ADT,并为getter提供合理的名称,然后使用高算术元组


编辑:然而,正如is7s在评论中指出的那样,有许多hackage软件包为任意长度的元组提供索引功能。

需要注意的是,
fst
snd
只允许一个人查看2元组。将它们推广到其他算术和运算很快就会变得很痛苦。例如,如果还想映射元组的第一个元素,则必须引入另一个组合符(记录在案,它作为
Control.Arrow.first
)存在于两个元组中。这很快导致高算术元组的组合数激增

也就是说,
lens
提供了一些处理元组的好工具。提供多个索引透镜
\u 1
\u 2
等,允许访问最高达arity 9的元组的第一、第二等元素

比如说,

>>> import Control.Lens
>>> let t = (1,2,3,5,6,7,2)
>>> t ^._1
1
>>> t & _1 .~ 'a'
('a',2,3,5,6,7,2)
>>> t & _1 +~ 41
(42,2,3,5,6,7,2)
>>> over _1 (+1) t
(2,2,3,5,6,7,2)

您可能还对中的元组实例感兴趣。另外,
tuple lens
还提供了一些更通用的镜头,用于同时检查多个tuple条目。

这个和其他tuple商品在包装中提供。@is7s谢谢,我不知道这个问题答案可能是“因为没有人经常使用tuple”。当然不是大的。不,我提到的包不是用
TemplateHaskell
实现的。
Data.Tuple.Select
模块的实现方式与OP类似。