2013-04-17 107 views
7

为什么以下编译:Haskell - 模糊类型变量,为什么?

{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE OverlappingInstances #-} 

class IsList a where 
    isList :: a -> Bool 

instance IsList a where 
    isList x = False 

instance IsList [a] where 
    isList x = True 

main = print (isList 'a') >> print (isList ['a']) 

但改变mainthis

main = print (isList 42) >> print (isList [42]) 

提供了以下错误:

Ambiguous type variable `a0' in the constraints: 
    (Num a0) arising from the literal `42' at prog.hs:13:22-23 
    (IsList a0) arising from a use of `isList' at prog.hs:13:15-20 
Probable fix: add a type signature that fixes these type variable(s) 
In the first argument of `isList', namely `42' 
In the first argument of `print', namely `(isList 42)' 
In the first argument of `(>>)', namely `print (isList 42)' 

isList肯定是不是在Num类它?如果不是,为什么模棱两可呢?

回答

10

问题不在于isList,而在于常量42.常量'a'具有Char的具体类型。常数42没有具体类型。

ghci> :t 42 
42 :: Num a => a 

编译器需要一个具体的类型。它会工作,如果你改变主要以下内容:

main = print (isList (42 :: Int)) >> print (isList [42 :: Int]) 
+0

啊,谢谢,这是有道理的。它可以编译,如果它不知道它的类型。但为什么不在这里“违约”?为什么不默认为Integer? – Clinton

+0

编译器没有任何内容表明它应该将它视为Int。如果相同的标识符是...说...传递到需要一个Int的函数,那么类型将被统一为Int。但是它不会为你自动做出这样的假设。 – mightybyte

+9

@Clinton:只有在所有约束都只涉及标准类时才会执行默认操作。 'IsList'不是标准的类。使用'ExtendedDefaultRules'可以放宽这个要求。 – hammar

相关问题