制作(a,a)一个Functor [英] Making (a, 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 V2
s 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屋!