不,sqrt
不提供任何.Num
它的供应商fromIntegral
确实能够根据需要生产任何产品Num
,而sqrt
需要 aFloating
作为其输入。并且Floating
是的子类Num
。
所以很fromIntegral
高兴地答应了。既然它可以产生Num
任何类型,那么它肯定可以产生任何类型的任何子类Num
。所以无论它最终是什么具体的具体类型,它都是 in Floating
,因此它必然是 in Num
。
因此fromIntegral
提供它没有问题。
编辑: Floating
不是一种类型。它是一类类型。具体类型可能属于Floating
类型类。由于Floating
是 的子类Num
,因此这种类型也保证在Num
. 这不是由于您提到的“继承”而自动发生的事情。“继承”即子类关系是对特定类型的要求,该特定类型Floating
也将是(in)Num
即实现Num
的方法以及来自 的方法Floating
。
所以是的,(特定的,具体的)Floating
类型也可以被视为一种Num
类型。
另一方面,sqrt
产生与其输入类型相同的类型,因此它将是相同的具体Floating
类型。但floor
期望一个RealFrac
类型。
观察
> :t floor ----------
floor :: (Integral b, RealFrac a) => a -> b
> :t sqrt . fromIntegral ----------
sqrt . fromIntegral :: (Integral a, Floating c) => a -> c
> :t floor . sqrt ---------- ----------
floor . sqrt :: (Integral c, RealFrac b, Floating b) => b -> c
> :i Floating
class Fractional a => Floating a where
....
instance Floating Float
instance Floating Double
> :i RealFrac
class (Real a, Fractional a) => RealFrac a where
....
instance RealFrac Float
instance RealFrac Double
因此,该调用产生(并因此被接受)的具体类型sqrt
必须是 (in)RealFrac
和Floating
.
由于从该应用程序链之外没有观察到它可能是任何兼容类型,因此是模棱两可的;但是键入 defaulting会启动并选择Double
,除非您更改了默认值。