[GHC] #10434: SPECIALISE instance does not specialize as far as SPECIALISE for type signatures
GHC
ghc-devs at haskell.org
Tue May 19 16:38:14 UTC 2015
#10434: SPECIALISE instance does not specialize as far as SPECIALISE for type
signatures
-------------------------------------+-------------------------------------
Reporter: | Owner:
andreas.abel | Status: new
Type: bug | Milestone:
Priority: normal | Version: 7.8.3
Component: Compiler | Operating System: Unknown/Multiple
Keywords: | Type of failure: None/Unknown
Architecture: | Blocked By:
Unknown/Multiple | Related Tickets:
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
{{{#!hs
type FreeM c = Reader (FreeEnv c) c
class Free' a c where
freeVars' :: (Monoid c) => a -> FreeM c
instance (Free' a c, Free' b c) => Free' (a,b) c where
{-# SPECIALIZE instance (Free' a All, Free' b All) => Free' (a,b) All
#-}
{-# SPECIALIZE freeVars' :: (Free' a Any, Free' b Any) => (a,b) -> FreeM
Any #-}
freeVars' (x,y) = freeVars' x `mappend` freeVars' y
}}}
I would expect these two specialize pragmas to work similarily. However,
the interface file shows that the mappend for Any has been inlined, but
not the one for All.
If you look at the .hi file dump below, you see
{{{
Data.Monoid.mappend
@ Data.Monoid.All
$dMonoid
}}}
generated by the SPECIALIZE instance, and
{{{
case (...) of wild1 {
GHC.Types.False
-> eta1
`cast`
(Control.Monad.Trans.Reader.NTCo:ReaderT[0]
<Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.Any>_R
<Data.Functor.Identity.Identity>_R
<Data.Monoid.Any>_N)
eta2
GHC.Types.True
-> GHC.Types.True
}}}
generated by the SPECIALIZE for the type signature.
For All, mappend is called from the dictionary dMonoid, which is still
passed around, whereas for Any, the disjunction has been inlined.
{{{
$fFree'(,)c_$s$cfreeVars' :: Agda.TypeChecking.Free.Lazy.Free'
a Data.Monoid.All
-> Agda.TypeChecking.Free.Lazy.Free' b
Data.Monoid.All
-> Data.Monoid.Monoid Data.Monoid.All
-> (a, b)
-> Agda.TypeChecking.Free.Lazy.FreeM
Data.Monoid.All
{- Arity: 4, HasNoCafRefs,
Strictness: <L,1*C1(C1(U))><L,1*C1(C1(U))><L,U(U,U,U)><S,1*U(U,U)>,
Unfolding: InlineRule (4, True, False)
(\ @ a
@ b
$dFree' :: Agda.TypeChecking.Free.Lazy.Free' a
Data.Monoid.All
$dFree'1 :: Agda.TypeChecking.Free.Lazy.Free' b
Data.Monoid.All
$dMonoid :: Data.Monoid.Monoid Data.Monoid.All
ds :: (a, b) ->
case ds of wild { (,) x y ->
let {
eta :: Control.Monad.Trans.Reader.ReaderT
(Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.All)
Data.Functor.Identity.Identity
Data.Monoid.All
= $dFree'
`cast`
(Agda.TypeChecking.Free.Lazy.NTCo:Free'[0]
<a>_N <Data.Monoid.All>_N)
$dMonoid
x
} in
let {
eta1 :: Control.Monad.Trans.Reader.ReaderT
(Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.All)
Data.Functor.Identity.Identity
Data.Monoid.All
= $dFree'1
`cast`
(Agda.TypeChecking.Free.Lazy.NTCo:Free'[0]
<b>_N <Data.Monoid.All>_N)
$dMonoid
y
} in
(\ eta2 :: Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.All ->
Data.Monoid.mappend
@ Data.Monoid.All
$dMonoid
(eta
`cast`
(Control.Monad.Trans.Reader.NTCo:ReaderT[0]
<Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.All>_R
<Data.Functor.Identity.Identity>_R
<Data.Monoid.All>_N)
eta2)
`cast`
(Data.Functor.Identity.NTCo:Identity[0]
<Data.Monoid.All>_R)
(eta1
`cast`
(Control.Monad.Trans.Reader.NTCo:ReaderT[0]
<Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.All>_R
<Data.Functor.Identity.Identity>_R
<Data.Monoid.All>_N)
eta2)
`cast`
(Data.Functor.Identity.NTCo:Identity[0]
<Data.Monoid.All>_R))
`cast`
(Trans
(<Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.All>_R
->_R Sym (Data.Functor.Identity.NTCo:Identity[0]
<Data.Monoid.All>_R))
(Sym (Control.Monad.Trans.Reader.NTCo:ReaderT[0]
<Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.All>_R
<Data.Functor.Identity.Identity>_R
<Data.Monoid.All>_N))) }) -}
2292db791a93ca783c0315a38fa7d8f1
$fFree'(,)c_$s$cfreeVars'1 :: Agda.TypeChecking.Free.Lazy.Free'
a Data.Monoid.Any
-> Agda.TypeChecking.Free.Lazy.Free' b
Data.Monoid.Any
-> (a, b)
-> Agda.TypeChecking.Free.Lazy.FreeM
Data.Monoid.Any
{- Arity: 3, HasNoCafRefs,
Strictness: <L,1*C1(C1(U))><L,1*C1(C1(U))><S,1*U(U,U)>,
Unfolding: InlineRule (3, True, False)
(\ $dFree' :: Agda.TypeChecking.Free.Lazy.Free' a
Data.Monoid.Any
$dFree'1 :: Agda.TypeChecking.Free.Lazy.Free' b
Data.Monoid.Any
ds :: (a, b) ->
case ds of wild { (,) x y ->
let {
eta :: Control.Monad.Trans.Reader.ReaderT
(Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.Any)
Data.Functor.Identity.Identity
Data.Monoid.Any
= $dFree'
`cast`
(Agda.TypeChecking.Free.Lazy.NTCo:Free'[0]
<a>_N <Data.Monoid.Any>_N)
Data.Monoid.$fMonoidAny
x
} in
let {
eta1 :: Control.Monad.Trans.Reader.ReaderT
(Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.Any)
Data.Functor.Identity.Identity
Data.Monoid.Any
= $dFree'1
`cast`
(Agda.TypeChecking.Free.Lazy.NTCo:Free'[0]
<b>_N <Data.Monoid.Any>_N)
Data.Monoid.$fMonoidAny
y
} in
(\ eta2 :: Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.Any ->
case (eta
`cast`
(Control.Monad.Trans.Reader.NTCo:ReaderT[0]
<Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.Any>_R
<Data.Functor.Identity.Identity>_R
<Data.Monoid.Any>_N)
eta2)
`cast`
(Data.Functor.Identity.NTCo:Identity[0]
(Data.Monoid.NTCo:Any[0])) of wild1 {
GHC.Types.False
-> eta1
`cast`
(Control.Monad.Trans.Reader.NTCo:ReaderT[0]
<Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.Any>_R
<Data.Functor.Identity.Identity>_R
<Data.Monoid.Any>_N)
eta2
GHC.Types.True
-> GHC.Types.True
`cast`
(Sym (Data.Functor.Identity.NTCo:Identity[0]
(Data.Monoid.NTCo:Any[0]))) })
`cast`
(Sym (Control.Monad.Trans.Reader.NTCo:ReaderT[0]
<Agda.TypeChecking.Free.Lazy.FreeEnv
Data.Monoid.Any>_R
<Data.Functor.Identity.Identity>_R
<Data.Monoid.Any>_N)) }) -}
2292db791a93ca783c0315a38fa7d8f1
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10434>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list