繁体   English   中英

为什么GHC在这里推断出单态类型,即使禁用了MonomorphismRestriction?

[英]Why does GHC infer a monomorphic type here, even with MonomorphismRestriction disabled?

这是通过解析`f = f(<*>)pure`的类型来提示的,它讨论了一个更复杂的例子,但这个也有效。

以下定义编译没有问题:

w :: Integral a => a
w = fromInteger w

......当然,它在运行时并不起作用 ,但这不是问题所在。 关键是w本身的定义使用w :: Integer 的专用版本 显然,这一个合适的实例,因此一个类型。

但是,如果我们删除签名,那么GHC不会推断出上述类型,而只会推断具体的类型:

w' = fromInteger w'
GHCi> :t w
w :: Integral a => a
GHCi> :t w'
w' :: Integer

好吧,当我看到这个时,我很确定这是工作中的单态限制。 众所周知,例如

i = 3
GHCi> :t i
i :: Integer

虽然i :: Num p => p是完全可能的。 实际上,如果-XNoMonomorphismRestriction是活动的,即如果禁用单态限制, 推断i :: Num p => p

但是,在w'情况下,即使禁用单态限制, 仅推断出Integer类型。

要指出这与默认有关:

fromFloat :: RealFrac a => Float -> a
q :: RealFrac a => a
q = fromFloat q
q' = fromFloat q'
GHCi> :t q
q :: RealFrac a => a
GHCi> :t q'
q' :: Float

为什么不推断出多态类型?

多态递归(函数调用自身的类型与调用它的类型不同) 总是需要类型签名。 完整的解释见Haskell 2010报告的第4.4.1节

如果定义变量f而未提供相应的类型签名声明,则在其自己的声明组外部使用f (参见第4.5节 )将被视为具有相应的推断或主体类型。 但是,为了确保仍然可以进行类型推断,定义的出现以及其声明组中f所有使用必须具有相同的单态类型(通过泛化获得主要类型,如第4.5.2节所述)。

后面的同一部分介绍了类型签名支持的多态递归示例。

我的理解是,在存在多态递归的情况下,无辅助类型推断通常是不可判定的,所以Haskell甚至都没有尝试过。

在这种情况下,类型检查器以

w :: a

其中a是元变量。 由于fromInteger在其自己的声明中被调用w作为参数(因此在其声明组中),因此类型检查器将aInteger统一起来。 没有变量可以概括。

由于同样的原因,对程序进行略微修改会产生不同的结果:

v = fromIntegral v

根据你原来的推理,Haskell会推断v :: forall a. Num a => a v :: forall a. Num a => a ,默认RHS上的v键入Integer

v :: forall a. Num a => a
v = fromIntegral (v :: Integer)

但相反,它以v :: a开头。 由于v传递给fromIntegral ,它强加Integral a 最后,它概括a 最终,程序结果是

v :: forall a. Integral a => a
v = fromIntegral (v :: a)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM