Code given below compiles, ok.
data Car p q r = Car {company :: p
, model :: q
, year ::r
} deriving (Show)
tellCar :: (Show a) => Car String String a -> String
What are the basic principles/ conventions / logic which can remind me that I need to take 'Show a' only in 'tellCar', not any other option? Where can I find resource to learn such principles/ conventions / logic?
If I mistakenly take 'Show Car' in the tellCar, following error message is received on compilation:
*Main> :load "/home/optimight/baby.hs"
[1 of 1] Compiling Main ( /home/optimight/baby.hs, interpreted )
/home/optimight/baby.hs:96:18:
Expecting three more arguments to `Car'
In the type signature for `tellCar':
tellCar :: Show Car => Car String String a -> String
Failed, modules loaded: none.
If I mistakenly take 'Show z' in the tellCar, following error message is received on compilation:
*Main> :load "/home/optimight/baby.hs"
[1 of 1] Compiling Main ( /home/optimight/baby.hs, interpreted )
/home/optimight/baby.hs:96:1:
Ambiguous constraint `Show z'
At least one of the forall'd type variables mentioned by the constraint
must be reachable from the type after the '=>'
In the type signature for `tellCar':
tellCar :: Show z => Car String String a -> String
Failed, modules loaded: none.
If I mistakenly take 'Show String' in the tellCar, following error message is received on compilation:
Prelude> :load "/home/optimight/baby.hs"
[1 of 1] Compiling Main ( /home/optimight/baby.hs, interpreted )
/home/optimight/baby.hs:96:1:
Non type-variable argument in the constraint: Show String
(Use -XFlexibleContexts to permit this)
In the type signature for `tellCar':
tellCar :: Show String => Car String String a -> String
Failed, modules loaded: none.