简体   繁体   中英

GHC 7.8 binding substitution fails to type check

Given the support code:

{-# 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

In GHC 7.6, I can write:

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

And that type checks, and prints:

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

However, in GHC 7.8 I get:

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

But, if I refactor to:

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

Then it works properly in both GHC 7.8 and GHC 7.6. Why?

The logic behind the support code is an instance for Show (a -> b) with Show context to force type defaulting, then a way of handling default atoms (with Eq ), and a way of moving something back over an -> for Testable2 . The code is designed to allow variable-arity QuickCheck properties, and is taken from hlint .

It seems that test (\\ x -> x) does not even compile with GHC 7.6.3. On the other hand:

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

compiles with both. I suspect defaulting not taking place for ungeneralized/monomorphic type variables in combination with special built-in treatment of ($) .

Copied from users kosmikus' comment to the question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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