# How to write a function whose both parameters and results are polymorphic in Haskell

How can I write a function like int gog(float i) and float gog(int i) (which is usually called "overloading")? Some simple overloads can be achieved by

class PP a where gog :: a -> Int instance PP Bool where gog _ = 1 instance PP Char where gog _ = 1

But the above example only makes the parameter polymorphic. If we want to make both the parameter and result polymorphic, we have to write something like this:

class PP a where gog :: Uu b => a -> b class UU a where -- This function can convert between different types of UU. fromUuToUu :: UU b => a -> b

Without fromUuToUu, the polymorphism in the result of gog is impossible. But I can't write fromUuToUu, and that is relevant to the theme of this question, which is how to make a function whose parameter and result are both polymorphic.

## Answers

{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances #-} class Poly a b where gog :: a -> b instance Poly Int String where gog = show instance Poly String Int where gog = read instance Poly Int Float where gog = fromIntegral instance Poly Float Float where gog = (*) 2

gog is now "full" polymorphic.