Reputation: 34119
I have many type declarations:
module SumProduct where
data GuessWhat = Chickenbutt deriving (Eq, Show)
data Id a = MkId a deriving (Eq, Show)
data Product a b = Product a b deriving (Eq, Show)
data Sum a b = First a
| Second b
deriving (Eq, Show)
data RecordProduct a b = RecordProduct { pfirst :: a , psecond :: b }
deriving (Eq, Show)
newtype NumCow = NumCow Int deriving (Eq, Show)
newtype NumPig = NumPig Int deriving (Eq, Show)
data Farmhouse = Farmhouse NumCow NumPig deriving (Eq, Show)
type Farmhouse' = Product NumCow NumPig
newtype NumSheep = NumSheep Int deriving (Eq, Show)
data BigFarmhouse = BigFarmhouse NumCow NumPig NumSheep deriving (Eq, Show)
type BigFarmhouse' = Product NumCow (Product NumPig NumSheep)
type Name = String
type Age = Int
type LovesMud = Bool
type PoundsOfWool = Int
data CowInfo = CowInfo Name Age
deriving (Eq, Show)
data PigInfo = PigInfo Name Age LovesMud deriving (Eq, Show)
data SheepInfo = SheepInfo Name Age PoundsOfWool deriving (Eq, Show)
data Animal = Cow CowInfo
| Pig PigInfo
| Sheep SheepInfo
deriving (Eq, Show)
type Animal' = Sum CowInfo (Sum PigInfo SheepInfo)(Sum PigInfo SheepInfo)
And play around in the prelude with:
Prelude> let bess = First (CowInfo "Bess" 4) :: Animal'
Prelude> let elmer' = Second (SheepInfo "Elmer" 5 5)
How it comes, that the first becomes the type bess :: Animal'
and the second elmer' :: Sum a SheepInfo
?
Upvotes: 1
Views: 95
Reputation: 1494
By default, Haskell infers the most general type that applies to the expression.
Here, you directly tell GHC what type bess
is, so it just checks if the type you provided is valid, but allows it to be more specific than the most general type.
Since you explicitly tell GHC that bess
has type Animal'
by the ::
operator (it's a language construct, not an actual operator defined in the standard library), GHC already knows that bess :: Animal'
. However, because you didn't provide any type for elmer'
, GHC will find the most general type for you.
In this case, the most general type is Sum a SheepInfo
because all GHC knows is that the Second
constructor takes a SheepInfo
, but has no idea of what First
should take. Thus, it infers it to a type variable a
.
Upvotes: 5