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)