2013-05-29 60 views
19

我有一个关于如何GHCi假定整数的类型的问题。Haskell:是没有类型的类。为什么是整数?

我在读Yes-No type class了解你一个Haskell。

这是一个链接,如果你想阅读整个事情。 http://learnyouahaskell.com/making-our-own-types-and-typeclasses#a-yes-no-typeclass

简而言之,本章说明了通过定义我自己的类,我可以创建一个可以处理很多类型的函数。

这本书定义YESNO类与功能

yesno :: a -> Bool 

,并Int作为YESNO类

instance YesNo Int where 
    yesno 0 = False 
    yesno _ = True 

的实例。当我装这对我GHCI和类型

yesno 0 

它返回错误。我认为这可能是因为GHCi无法分辨0是否意味着IntIntegerDoubleNum类中的其他类型。实际上,当我输入yesno(0 :: Int)它工作。

所以只是为了好玩我做了IntegerYesNo类的一个实例,写

​​

(请注意,我翻true和false) 又一次,我打字

yesno 0 

(不任何类型的声明),那么GHCi显示True

而且,当我输入

yesno $ fromIntegral 0 

它返回True,这意味着GHCI认为的fromIntegral 0类型是Integer

那么,这是否意味着,当我刚键入GHCI一个整数,它通常假定它的值是在代替Integer?我很困惑,因为​​3210回报Num a => a

回答

24

这是defaulting类型连同ghci中的扩展默认规则。

整数文字是多态的,它们的类型为Num a => a(因为它们代表fromInteger literal)。但是,当表达式应该被评估 - 例如打印其结果所必需的 - 表达式必须被赋予一个单形式。

其本身而言,

yesno 0 

强加给0两个约束Num aYesNo a,并且整个表达将具有不明确的类型

yesno 0 :: (Num a, YesNo a) => Bool 

(这是模糊的,因为在类型变量约束无法从=>右侧的类型中获得)。

一般来说,暧昧的类型是类型错误,但是,在某些情况下,不确定性是用默认类型实例化约束类型变量解决。在语言规范的规则是一个类型变量可以默认如果

在一个不明确的类型被发现的情况下,不明确的类型变量,v,是违约如果:

- `v` appears only in constraints of the form `C v`, where `C` is a class, and 
- at least one of these classes is a numeric class, (that is, `Num` or a subclass of `Num`), and 
- all of these classes are defined in the Prelude or a standard library (Figures 6.2–6.3 show the numeric classes, and Figure 6.1 shows the classes defined in the Prelude.) 

约束(Num a, YesNo a)满足前两个要求,但不是第三个要求。所以按照语言标准,它不是可以违约的,应该是一个类型错误。

然而,ghci中使用扩展的默认规则,并且还通过在前奏或标准库不定义的类约束默认类型的变量。

然后,它会选择这里Num约束默认情况下,除非明确的默认声明是在范围,这将是Integer,或者,如果Integer不满足约束,Double受审。

因此,当你有一个instance YesNo Integer,ghci可以成功地将类型变量a默认为Integer。但没有可用的这样的情况下,默认失败,因为没有默认的候选人有一个实例。

在第一种情况下
8

那么,这是否意味着,当我刚键入GHCI一个整数,它通常假定它的值是整型?

是的。基本上,GHCI将首先尝试Integer,如果失败,Double然后最后()来解析不明确的类型约束。你可以read the details about how this works in the GHC User's Guide

但是,请注意,在编译的模块,这些规则都有点严格。特别是,只有默认适用于标准类,所以你的例子不是没有类型注释的编译的模块中,除非您启用ExtendedDefaultRules扩展,为您提供了相同的行为GHCI工作。

1

尝试写:

Prelude> yesno (0 :: Int) 
False 
相关问题