softshipper
softshipper

Reputation: 34119

Construct a type

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

Answers (1)

baxbaxwalanuksiwe
baxbaxwalanuksiwe

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

Related Questions