2017-06-16 45 views
1

我有很多类型声明:构造一个类型

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

这与你的问题没有任何关系,但你可能想知道你不需要在'module SumProduct where'下面缩进所有东西。只需在第0列开始下一行,并且可以将所有顶级声明留在那里。 – dfeuer

回答

5

默认情况下,Haskell推断应用于表达式的最一般类型。

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

因为你明确告诉GHC是bess已经由::操作输入Animal'(这是一个语言结构,而不是在标准库中定义的实际操作),GHC已经知道bess :: Animal'。但是,因为您没有提供任何类型的elmer',GHC会为您找到最一般的类型。

在这种情况下,最普遍的类型是Sum a SheepInfo因为所有GHC知道的是,Second构造需要SheepInfo,但没有什么First应采取的想法。因此,它将其推断为类型变量a

+0

对于最“最普通的类型”,你是什么意思,你能举一个例子吗? –

+0

我称之为最普通的类型是假设数据信息较少的类型。例如,当你在Haskell中键入一个数字文字时,比如'23',它被推断为'Num a => a'。这就是为什么你可以做'2 * 0.5':'2'不是'Int',而是适应右边的数字,在这种情况下,它是一个浮点数。 – baxbaxwalanuksiwe