Polymorphic instances aren't automatically specialised
Related to #255 (closed). Given (roughly) the example from that ticket:
f :: (Storable a, Eq a) => T a
g :: T (Ptr a)
g = f
we find that g is not specialised. Adding a SPECIALISE pragma fixes this, but it ought not to be necessary.
The following module is a complete example:
module C where
class C a where f :: a -> a
newtype Id a = Id a
instance C (Id a) where f = id
g :: C a => Int -> a -> a
g 0 a = a
g n a = g (n-1) (f a)
h :: Int -> Id a -> Id a
h = g
j :: Int -> Id Int -> Id Int
j = g
We find that h passes a dictionary to g:
C.h =
\ (@ a_alq) (w_smq :: Int) (w1_smu :: C.Id a_alq) ->
case w_smq of _ { I# ww_sms ->
C.$wg @ (C.Id a_alq) (C.$fCId @ a_alq) ww_sms w1_smu
}
whereas j is specialised as desired, getting its own worker and no dictionaries:
C.j =
\ (w_smg :: Int) (w1_smk :: C.Id Int) ->
case w_smg of _ { I# ww_smi ->
(C.$wj ww_smi w1_smk)
`cast` (sym (C.NTCo:Id Int)
:: Int ~ C.Id Int)
}
If we add
{-# SPECIALISE g :: Int -> Id a -> Id a #-}
then h is specialised as desired.
Trac metadata
Trac field | Value |
---|---|
Version | 7.0.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |