16

我在玩类型类并做了这个:

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

class Secondable f where
  snd :: f a -> a

然后我尝试添加一个实现(,)并意识到我可以这样做:

instance Secondable ((,) a) where
  snd (x,y) = y

我很确定这是可行的,因为Secondable应该有那种类型(* -> *)((,) a)但是,我不知道如何实现Firstable绑定变量的((,) * a)位置*,在我的解释中,我试图做相当于:

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

有没有办法在 Haskell 中做到这一点?最好没有扩展?

4

3 回答 3

10

您可以像这样使用类型族(对 Edward 所写内容的不同看法):

{-# 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
于 2012-06-05T16:16:43.477 回答
1
class Firstable f where
    fst :: f a b -> a

class Secondable f where
    snd :: f a b -> b
于 2012-06-05T15:31:07.617 回答
1

MPTCS 和 Fundeps 或 TypeFamilies 可以提供参数保证更差的版本。

type family Fst p
type instance Fst (a,b) = a
type instance 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

...

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

于 2012-06-05T16:12:16.560 回答