元组的Haskell类型类

元组的Haskell类型类,haskell,typeclass,Haskell,Typeclass,我在玩TypeClass,并制作了以下内容: class Firstable f where fst :: f a -> a class Secondable f where snd :: f a -> a 然后,我尝试为(,)添加一个实现,并意识到我可以做到: instance Secondable ((,) a) where snd (x,y) = y 我很确定这是可行的,因为第二个应该有种类(*->*),其中(,)a)有那种类型,但是,我不知道如何为(,)*a

我在玩TypeClass,并制作了以下内容:

class Firstable f where
  fst :: f a -> a

class Secondable f where
  snd :: f a -> a
然后,我尝试为
(,)
添加一个实现,并意识到我可以做到:

instance Secondable ((,) a) where
  snd (x,y) = y
我很确定这是可行的,因为
第二个
应该有种类
(*->*)
,其中
(,)a)
有那种类型,但是,我不知道如何为
(,)*a)
实现
第一个
,其中
*
是绑定变量,在我的解释中,我试图做的等效于:

instance Firstable (flip (,) a) where ...

哈斯克尔有没有办法做到这一点?最好没有扩展?

参数保证较差的版本可以与MPTC和Fundeps或TypeFamilies一起使用

class Firstable f where
    fst :: f a b -> a

class Secondable f where
    snd :: f a b -> b
type family Fst p
type instance Fst (a,b) = a
type instance Fst (a,b,c) = a


但最终,您需要使用一些扩展。

您可以像这样使用类型族(与Edward所写的不同):


好的,否:您需要
类型同义词实例
,但类型同义词不能部分求值。但是您知道使用
MultiParamTypeClasses
的替代方案吗?这可能有点难看,但它是有效的。您可能会对tuple包如何处理这个问题感兴趣:这样,只有2个tuple才能成为该类的实例,不是吗?这有点违背了使用类型类的目的。@sepp2k首先,他从未指定用途,我将其解释为他只想泛化(至少)两个参数的类型构造函数。其次,他的两个原始类具有完全相同的签名,这意味着他要么搞错了,要么他应该只使用一个类来描述这两个字段。@GabrielGonzalez是的,我希望元组能够实现为(,),(,)…如果你愿意接受从右边而不是从左边计数,这种方法实际上是可行的,但我不认为你会让它反过来工作。这是一个有趣的想法,尽管在这种情况下,你会想这样做:
fst::fa->a
snd::fa->b
,…是
类型实例fst(a,b,c)=b
应该改为读取类型实例Fst(a,b,c)=a
class First p where
   fst :: p -> Fst p

instance Fst (a,b) where
   fst (a,_) = a

instance Fst (a,b,c) where
   fst (a,_,_) = a
{-# LANGUAGE TypeFamilies #-}

class Firstable a where
  type First a :: *
  fst :: a -> First a

class Secondable a where
  type Second a :: *
  snd :: a -> Second a

instance Firstable (a,b) where
  type First (a, b) = a
  fst (x, _) = x

instance Secondable (a,b) where
  type Second (a, b) = b
  snd (_, y) = y