我一直在尝试了解 Haskell 如何处理子类型,所以我想出了以下代码片段:
{-# LANGUAGE RankNTypes #-}
f1 :: () -> Int
f1 _ = 5
f2 :: () -> (forall a. Integral a => a)
f2 = f1
该行f2 = f1
失败并出现意外错误消息:
Couldn't match type ‘a’ with ‘Int’
‘a’ is a rigid type variable bound by
the type signature for:
f2 :: forall a. Integral a => () -> a
似乎存在主义被提升为普遍存在,这当然是无意的。
我的猜测是,在实现方面f2
需要返回一个值和一个相应的字典,而f1
只返回一个 type 的值Int
。然而,从逻辑的角度来看,契约f2
是“一个来自()
某个未知实例的函数Integral
”并且f1
完美地满足了它。
GHC 应该做一些隐含的魔法来让它工作还是我错过了什么?