С учетом кода поддержки:
{-# 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 переменной arity, и берется из hlint.