Создание (a, a) функтора

Как я могу сделать (a, a) a Функтор без обращения к newtype ?

В основном я хочу, чтобы он работал так:

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

Но, конечно, это не законно способ выразить это:

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

Что мне действительно нужно, так это функция уровня типа, подобная этой: \ a -> (a, a) (неверный синтаксис). Может быть, псевдоним типа?

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

Я бы подумал, что это сработает, но это не так. Сначала я получаю такую ​​жалобу:

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'

Если я последую совету и добавлю расширение TypeSynonymInstances , я получу новую ошибку:

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

Ну, да, в том-то и дело! V2 имеет вид * -> * , который требуется от экземпляра Functor . Хорошо, хорошо, я могу использовать newtype вот так:

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

Но теперь мне нужно обильно разбросать V2 по всему моему коду вместо того, чтобы иметь дело с простыми кортежи, что лишает смысла превращать его в Functor ; в этот момент я мог бы создать свою собственную функцию vmap :: (a -> b) -> (a, a) -> (b, b) .

Так есть ли способ сделай это красиво, т.е. без newtype ?

19
задан Tom Crockett 27 January 2011 в 05:58
поделиться