类实例中的Int vs Integer

1 haskell

class Visible a where
 toString :: a -> String
 size   :: a -> Int

intToString :: (Integral t) => t -> String
intToString 0 = "0"
intToString 1 = "1"
intToString 2 = "2"
intToString 3 = "3"
intToString 4 = "4"
intToString 5 = "5"
intToString 6 = "6"
intToString 7 = "7"
intToString 8 = "8"
intToString 9 = "9"
intToString n 
 | ((div n 10) == 0) = (intToString (mod n 10))
 | otherwise         = (intToString (div n 10)) ++ (intToString (mod n 10))
Run Code Online (Sandbox Code Playgroud)

现在

instance Visible Int where
 toString = intToString
 size n   = length (toString n)
Run Code Online (Sandbox Code Playgroud)

如果我输入类似的内容(toString 55),会在提示符处给出一个关于模糊类型变量的错误

instance Visible Integer where
 toString = intToString
 size n   = length (toString n)
Run Code Online (Sandbox Code Playgroud)

才不是.

是什么赋予了?

Joh*_*n L 15

这里有两件事.请记住,Haskell中的数字文字是多态的.那是:

x = 55
Run Code Online (Sandbox Code Playgroud)

真正意思

x :: Num a => a
x = fromIntegral 55
Run Code Online (Sandbox Code Playgroud)

对于编写它们的任何地方的所有数字都是如此.这可能很难处理,所以GHCi实现了类型默认:它假定裸数是Integers或者Doubles类型是不明确的.

当您toString 55在GHCi提示符处写入时,GHCi会推断出(Visible a, Num a) => a数字55 的类型.如果您只有Visible Int范围,则类型默认值Integer不起作用,因为它不符合类约束(没有Visible Integer),所以GHCi抱怨模糊类型变量,因为它不知道要为表达式实例化哪个类型.如果你有Visible Integer范围,Integer的默认类型就可以了.

如果要使用Integer以外的类型,可以使用显式类型 toString (55 :: Int)