GHC 7.8绑定替换无法进行类型检查



给定支持代码:

{-# LANGUAGE ExtendedDefaultRules, DeriveDataTypeable #-}
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}
import Data.Typeable
default(A)
data A = A deriving (Eq,Show,Typeable)
class Show a => Testable2 a where
instance (Show a, Eq a) => Testable2 a where
instance (Show a, Testable2 b) => Testable2 (a -> b) where
instance (Show a, Show b) => Show (a -> b) where show _ = "<func>"
test :: (Show p, Typeable p, Testable2 p) => p -> IO ()
test = print . typeOf

在GHC 7.6中,我可以写:

main = test (f -> (f $))

这种类型检查并打印:

(A -> A) -> A -> A

然而,在GHC7.8我得到:

Main.hs:
    No instance for (Eq (a0 -> b0)) arising from a use of `test'

但是,如果我重构为:

main = let ff = f -> (f $) in test ff

然后它在GHC7.8和GHC7.6中都能正常工作。为什么?

支持代码背后的逻辑是Show (a -> b)Show上下文的一个实例,以强制类型默认,然后是一种处理默认原子的方式(使用Eq),以及一种将某些内容移回Testable2->的方式。该代码旨在允许可变arity QuickCheck属性,并取自hlint。

似乎test ( x -> x)甚至没有使用GHC 7.6.3进行编译。另一方面:

($$) = ($)
main = test ( f -> (f $$))

同时编译。我怀疑未泛化/单态类型变量与($)的特殊内置处理相结合不会发生默认。

复制自用户kosmikus对该问题的评论。

最新更新