Dato il codice di supporto:GHC 7.8 sostituzione vincolante non riesce a digitare il check
{-# 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, posso scrivere:
main = test (\f -> (f $))
E che tipo controlli, e le stampe:
(A -> A) -> A -> A
Tuttavia, in GHC 7.8 ottengo:
Main.hs:
No instance for (Eq (a0 -> b0)) arising from a use of `test'
Ma, se refactoring a:
main = let ff = \f -> (f $) in test ff
allora funziona correttamente sia in GHC 7.8 e 7.6 GHC. Perché?
La logica dietro il codice di supporto è un'istanza per Show (a -> b)
con Show
contesto di forzare tipo inadempiente, allora un modo di gestire atomi di default (con Eq
), e un modo di muoversi qualcosa su un ->
per Testable2
. Il codice è progettato per consentire le proprietà QuickCheck di variabili variabili e viene preso da hlint.
Cosa fornisce 'main = test ($)'? – bheklilr
Per rispondere alla mia domanda, in 7.8 dà lo stesso errore di 'test (\ f -> (f $))': "Nessuna istanza per' (Eq (a0 -> b0)) 'derivante dall'uso di' test '" – bheklilr
Stranamente, se faccio 'main = test ((\ f -> (f $)) :: (a -> b) -> a -> b)' poi compila e produce '(A -> A) -> A -> A', ma se lascio la firma del tipo ottengo un errore. Questo funziona anche per 'main = test (($) :: (a -> b) -> a -> b)'. – bheklilr