出力する値を型を指定することにより変化させる( Use -XTypeSynonymInstances if you want to disable this)

maxBound、minBound は出力する型を指定するをその型が表現できる最大値、最小値を出力します。

> maxBound::Char -->'\1114111'
> maxBound::Int  --> 2147483647
> minBound::Char -->'\NUL'
> minBound::Int  --> -2147483648

これと同じように自分でも出力する型を指定すると動作の変わる関数を定義したくなって以下の型クラスとインスタンスを定義してみました。
returnNum というIntegerを引数とする関数に出力する型を指定して、Integerを返させたり、Stringを返させたりしたい訳です。

class   Rnum  a       where  returnNum :: Integer -> a

instance Rnum Integer where  returnNum n = n

instance Rnum String  where  returnNum n = (show n)

instance Rnum String where returnNum n = (show n) でエラーになります。

type.hs:7:10:
    Illegal instance declaration for `Rnum String'
      (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 `Rnum String'
Failed, modules loaded: none.

コンパイラのオプションに -XTypeSynonymInstancesをつけろということらしいので。{-# LANGUAGE TypeSynonymInstances #-}を指定するとOKでした。

{-# LANGUAGE TypeSynonymInstances #-}

class   Rnum  a       where  returnNum :: Integer -> a

instance Rnum Integer where  returnNum n = n

instance Rnum String  where  returnNum n = (show n)

{-
> :r
Ok, modules loaded: Main.
-- これで出力をIntegerを指定するとIntegerが返り、Stringを指定するとStringが返ります。
> returnNum 99 :: Integer -- > 99
> returnNum 99 :: String  -- > "99"

-- 同じ関数の結果でも、文脈から判断して働きます。
> 101   +   returnNum 99    -- > 200
> "101" ++  returnNum 99 -- > "10199"
-}

文脈とは何か:文の脈絡。コンテクスト。 文章の流れの中にある意味内容のつながりぐあい。(kotobank > 文脈とは

この他に stackoverflow には -XFlexibleInstancesオプションんを指定する方法も紹介されています。

{-# LANGUAGE FlexibleInstances #-}

newtype Wrapper = Wrapper String deriving Show

class   Rnum  a       where  returnNum :: Integer -> a

instance Rnum Integer where  returnNum n = n

instance Rnum Wrapper where returnNum n = Wrapper (show n)

{-
 :r
[1 of 1] Compiling Main             ( type.hs, interpreted )
Ok, modules loaded: Main.
> returnNum 99 :: Integer -- > 99
> returnNum 99 :: Wrapper -- > Wrapper "99"
-}