Haskell类型变量疑问:为何Dog 12的类型不是Animal a Integer?
问题解答
先看你给出的代码示例:
ghci> data Animal a b = Cat a | Dog b | Rat ghci> data BreedOfCat = Siamese | Persian | Moggie ghci> :t Cat Siamese Cat Siamese :: Animal BreedOfCat b ghci> :t Cat Persian Cat Persian :: Animal BreedOfCat b ghci> :t Dog 12 Dog 12 :: Num b => Animal a b ghci> :t Dog "Fifo" Dog "Fifo" :: Animal a String ghci> :t Rat Rat :: Animal a b
核心原因:数字字面量的多态性 vs 字符串字面量的确定性
- 字符串字面量(比如
"Fifo")的类型是固定的String,没有任何类型类约束,所以传给Dog构造器后,直接得到Animal a String的确定类型。 - 而数字字面量(比如
12)是多态的,它属于Num类型类的所有实例。Haskell不会默认把它绑定到Integer(或Int),而是保留其多态性,用类型约束Num b =>表示:只要b是Num类型类的实例(比如Integer、Int、Float、Double等),Dog 12都能适配成Animal a b的类型。
如何得到Animal a Integer?
如果你想让Dog 12的类型固定为Animal a Integer,只需要显式指定数字的类型:
ghci> :t Dog (12 :: Integer) Dog (12 :: Integer) :: Animal a Integer
内容的提问来源于stack exchange,提问作者tanvi
相关产品推荐
相关产品推荐

