构造一个类型

时间:2017-06-16 14:52:12

标签: haskell

我有很多类型声明:

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)

在前奏中玩弄:

Prelude> let bess = First (CowInfo "Bess" 4) :: Animal'
Prelude> let elmer' = Second (SheepInfo "Elmer" 5 5)

怎么来的,第一个成为bess :: Animal'类型,第二个成为elmer' :: Sum a SheepInfo

1 个答案:

答案 0 :(得分:5)

默认情况下,Haskell推断出适用于表达式的最常规类型。

在这里,你直接告诉GHC bess是什么类型,所以它只是检查你提供的类型是否有效,但是它允许它比最通用的类​​型更具体。

由于您明确告诉GHC bess Animal'运算符类型为::(它是一种语言结构,而不是标准库中定义的实际运算符),GHC已经知道bess :: Animal'。但是,由于您没有为elmer'提供任何类型,GHC会为您找到最常用的类型。

在这种情况下,最常见的类型是Sum a SheepInfo,因为所有GHC都知道Second构造函数需要SheepInfo,但不知道First应该是什么采取。因此,它将其推断为类型变量a