Define function independent of specific value constructor (templates?)

106 Views Asked by At

Is it possible to write a function for generic types (in this case applicatives) without making assumptions about the name of type constructors?

I can write the following:

f :: Maybe a -> Maybe a
f (Just a) = (Just a)

That one works on Maybes and only instances with the Just constructor.

But say I had different types that have a value constructor that had the same name as the type constructor:

data T a = T a

instance Functor T where
  fmap f (T a) = T (f a)

instance Applicative T where
  pure = T
  (T f) <*>  (T something) = fmap f (T something)




data U a = U a

instance Functor U where
  fmap f (U a) = U (f a)

instance Applicative U where
  pure = U
  (U f) <*>  (U something) = fmap f (U something)

In this case T and U are isomorphic, but maybe they also would have constructors that are special to either one in a real example... does not matter here.

Now what if wanted a function that operates both on T and U... I could write the function two times, like so:

gt :: T a -> T a
gt (T x) =  T x

gu :: U a -> U a
gu (U x) =  U x

Is there also a way to make a template for this function like this?

g :: (Applicative f) => f a -> f a
g (f x) = f x

That will give me a syntax error for some reason, even though it has the same structure as gt and gu.

If there is no way to do that then why not?

0

There are 0 best solutions below