给出支持代码:
{-# 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
然而,在GHC 7.8中,我得到了:
Main.hs:
No instance for (Eq (a0 -> b0)) arising from a use of `test'
但是,如果我重构:
main = let ff = \f -> (f $) in test ff
然后它在GHC 7.8和GHC 7.6中都能正常工作。为什么呢?
支持代码背后的逻辑是Show (a -> b)
的实例,Show
上下文强制类型默认,然后是一种处理默认原子的方法(使用Eq
),以及将某些内容移回->
Testable2
。该代码旨在允许可变的QuickCheck属性,并取自hlint。
答案 0 :(得分:1)
似乎test (\ x -> x)
甚至没有用GHC 7.6.3编译。另一方面:
($$) = ($)
main = test (\ f -> (f $$))
编译两者。我怀疑默认不会发生非广义/单态类型变量与($)
的特殊内置处理相结合。
从用户kosmikus&#39;复制评论这个问题。