制作(a,a)一个Functor

Tom*_*ett 19 haskell types functor typeclass

我怎样才能让(a, a)一个Functor不诉诸newtype

基本上我希望它像这样工作:

instance Functor (a, a) where
  fmap f (x, y) = (f x, f y)
Run Code Online (Sandbox Code Playgroud)

但当然,这不是表达它的合法方式:

Kind mis-match
The first argument of `Functor' should have kind `* -> *',
but `(a, a)' has kind `*'
In the instance declaration for `Functor (a, a)'
Run Code Online (Sandbox Code Playgroud)

我真正想要的是这样的类型级函数:( \a -> (a, a)语法无效).也许这是一个类型别名?

type V2 a = (a, a)
instance Functor V2 where
    fmap f (x, y) = (f x, f y)
Run Code Online (Sandbox Code Playgroud)

我认为这会奏效,但事实并非如此.首先我得到这个投诉:

Illegal instance declaration for `Functor V2'
(All instance types must be of the form (T t1 ... tn)
 where T is not a synonym.
 Use -XTypeSynonymInstances if you want to disable this.)
In the instance declaration for `Functor V2'
Run Code Online (Sandbox Code Playgroud)

如果我按照建议并添加TypeSynonymInstances扩展名,我会收到一个新错误:

Type synonym `V2' should have 1 argument, but has been given 0
In the instance declaration for `Functor V2'
Run Code Online (Sandbox Code Playgroud)

恩,呃,这就是重点!V2具有实例* -> *所需的种类Functor.好吧,好吧,我可以使用newtype这样的:

newtype V2 a = V2 (a, a)
instance Functor V2 where
  fmap f (V2 (x, y)) = V2 (f x, f y)
Run Code Online (Sandbox Code Playgroud)

但是现在我必须V2在我的代码中自由地散布,而不仅仅是能够处理简单的元组,这种方法使得它成为了一个Functor; 在那一点上,我不妨创造自己的功能vmap :: (a -> b) -> (a, a) -> (b, b).

那么有没有办法很好地做到这一点,即没有newtype

Joh*_*n L 16

正如其他人所说,如果不诉诸新类型或数据声明,就无法做到这一点.但是,你看过Control.Arrow吗?其中许多函数对元组非常有用,例如:

vmap :: (a -> b) -> (a,a) -> (b,b)
vmap f = f *** f
Run Code Online (Sandbox Code Playgroud)