我有很多类型声明:
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
?
答案 0 :(得分:5)
默认情况下,Haskell推断出适用于表达式的最常规类型。
在这里,你直接告诉GHC bess
是什么类型,所以它只是检查你提供的类型是否有效,但是它允许它比最通用的类型更具体。
由于您明确告诉GHC bess
Animal'
运算符类型为::
(它是一种语言结构,而不是标准库中定义的实际运算符),GHC已经知道bess :: Animal'
。但是,由于您没有为elmer'
提供任何类型,GHC会为您找到最常用的类型。
在这种情况下,最常见的类型是Sum a SheepInfo
,因为所有GHC都知道Second
构造函数需要SheepInfo
,但不知道First
应该是什么采取。因此,它将其推断为类型变量a
。