Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making (a, a) a Functor

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?

like image 232
Tom Crockett Avatar asked Jan 27 '11 04:01

Tom Crockett


People also ask

How do you make a functor?

In order to create a functor, we first have to create a class whose object we can call like a function. So, we have created a class named Greet . Here, we have overloaded the function call operator () using: class Greet { public: // overload function call operator void operator()() { cout << "Hello World!"; } };

What does functor mean?

Definition of functor : something that performs a function or an operation.

What is the difference between a functor and a function pointer?

A function pointer allows a pointer to a function to be passed as a parameter to another function. Function Objects (Functors) - C++ allows the function call operator() to be overloaded, such that an object instantiated from a class can be "called" like a function.

What is a functor in programming?

In functional programming, a functor is a design pattern inspired by the definition from category theory, that allows for a generic type to apply a function inside without changing the structure of the generic type. This idea is encoded in Haskell using type class.


1 Answers

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
like image 81
John L Avatar answered Nov 15 '22 19:11

John L