制作(a,a)一个Functor [英] Making (a, a) a Functor

查看:115
本文介绍了制作(a,a)一个Functor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在不诉诸的情况下制作(a,a) a Functor newtype



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

 实例Functor(a,a)其中
fmap f(x,y)=(fx,fy)

但当然这不是一种合法的表达方式:

  Kind mis-匹配
'Functor'的第一个参数应该有`* - > *',
但是`(a,a)'有`*'
在`Functor(a,a)'

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

  type V2 a =(a,a)
实例Functor V2其中
fmap f(x,y)=(fx,fy)

我认为这可行,但事实并非如此。首先,我收到了这个投诉:

$ $ $ $ $ $ $ $ $ $ $ $ $ $' form(T t1 ... tn)
其中T不是同义词
如果你想禁止这个,使用-XTypeSynonymInstances。)
在`Functor V2'的实例声明中

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

 类型同义词`V2'应该有1个参数,但已经给出0 
在'Functor V2'的实例声明中,

好吧,那就是重点! V2 has kind * - > * 这就是 Functor 实例的要求。好吧,我可以像这样使用 newtype

  newtype V2 a = V2(a,a)
实例Functor V2其中
fmap f(V2(x,y))= V2(fx,fy)

但是现在我必须在我的代码中大量地散布 V2 s,而不是仅仅能够处理简单的元组,这使得它成为 Functor ;在这一点上,我可能会做我自己的功能 vmap ::(a - > b) - > (a,a) - > (b,b)



那么有没有什么办法可以做到这一点,即没有 newtype code>?

解决方案

正如其他人所说的,如果不采用新类型或数据声明,就无法做到这一点。但是,你看过 Control.Arrow 吗?例如:

  vmap ::(a  - > b) - >这些功能对元组非常有用。 (a,a) - > (b,b)
vmap f = f *** f


How can I make (a, a) a Functor without resorting to a newtype?

Basically I want it to work like this:

instance Functor (a, a) where
  fmap f (x, y) = (f x, f y)

But of course that's not a legal way to express it:

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

What I really want is a type-level function like this: \a -> (a, a) (invalid syntax). So a type alias, perhaps?

type V2 a = (a, a)
instance Functor V2 where
    fmap f (x, y) = (f x, f y)

I would think this would work, but it doesn't. First I get this complaint:

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'

If I follow the advice and add the TypeSynonymInstances extension, I get a new error:

Type synonym `V2' should have 1 argument, but has been given 0
In the instance declaration for `Functor V2'

Well, duh, that's the point! V2 has kind * -> * which is what is required of a Functor instance. Well, ok, I can use a newtype like this:

newtype V2 a = V2 (a, a)
instance Functor V2 where
  fmap f (V2 (x, y)) = V2 (f x, f y)

But now I've got to sprinkle V2s liberally throughout my code instead of just being able to deal with simple tuples, which kind of defeats the point of making it a Functor; at that point I might as well make my own function vmap :: (a -> b) -> (a, a) -> (b, b).

So is there any way to do this nicely, i.e. without a newtype?

解决方案

As others have stated, there's no way to do this without resorting to newtypes or data declarations. However, have you looked at Control.Arrow? Many of those functions are very useful with tuples, for example:

vmap :: (a -> b) -> (a,a) -> (b,b)
vmap f = f *** f

这篇关于制作(a,a)一个Functor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆