У меня есть следующий класс типов и экземпляры:
class StatType a where
toDouble :: a -> Double
instance StatType Double where
toDouble = id
instance Integral a => StatType a where
toDouble = fromIntegral
avg :: StatType a => [a] -> Double
avg = undefined
Но тогда выражение
*Example> avg ([1,2,3,4] :: [Double])
сообщает об ошибке типа относительно перекрывающихся экземпляров
Overlapping instances for StatType Double
arising from a use of `avg'
Matching instances:
instance StatType Double -- Defined at Example.hs:61:10
instance Integral a => StatType a -- Defined at Example.hs:63:10
Система типов не может выбирать между этими двумя экземплярами. Однако Double
не является типом Integral
.
*Example> :i Double
data Double = GHC.Types.D# GHC.Prim.Double#
-- Defined in `GHC.Types'
instance StatType Double -- Defined at Example.hs:
instance Enum Double -- Defined in `GHC.Float'
instance Eq Double -- Defined in `GHC.Classes'
instance Floating Double -- Defined in `GHC.Float'
instance Fractional Double -- Defined in `GHC.Float'
instance Num Double -- Defined in `GHC.Float'
instance Ord Double -- Defined in `GHC.Classes'
instance Read Double -- Defined in `GHC.Read'
instance Real Double -- Defined in `GHC.Float'
instance RealFloat Double -- Defined in `GHC.Float'
instance RealFrac Double -- Defined in `GHC.Float'
instance Show Double -- Defined in `GHC.Float'
И я не думаю, что под Integral
подразумевается что-то из этого или что-то в этом роде? fromIntegral (3 :: Double)
вызывает ошибку типа, поскольку Double
не является экземпляром Integral
.
Почему они перекрываются?
Спасибо!
OverlappingInstances
позволяет это, выбирая наиболее конкретный экземпляр. Иногда это полезно, но если бы вы также определили, скажем,instance Rational a => StatType a
, это немедленно снова сломалось бы. 16.05.2014