Nano Hash - криптовалюты, майнинг, программирование

Перекрывающиеся экземпляры для типов Double и Integral

У меня есть следующий класс типов и экземпляры:

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.

Почему они перекрываются?

Спасибо!

16.05.2014

Ответы:


1

Проще говоря, GHC работает

Когда GHC пытается разрешить, скажем, ограничение C Int Bool, он пытается сопоставить каждое объявление экземпляра с ограничением, создавая заголовок объявления экземпляра. Рассмотрим эти объявления:

instance context1 => C Int a     where ...  -- (A)
instance context2 => C a   Bool  where ...  -- (B)

Поведение GHC по умолчанию заключается в том, что только один экземпляр должен соответствовать ограничению, которое он пытается разрешить. Например, ограничение C Int Bool соответствует экземплярам (A) и (B) и, следовательно, будет отклонено; в то время как C Int Char соответствует только (A) и, следовательно, выбирается (A).

Заметь

  • При сопоставлении GHC не учитывает контекст объявления экземпляра (context1 и т. д.).

Так что ghc не видит

instance StatType Double 
instance Integral a => StatType a 

Он видит

instance StatType Double 
instance StatType a 

Которые явно пересекаются.

Причина, по которой это работает, заключается в том, что классы типов открыты. Экземпляра для Integral Double сейчас нет, но кто-то может импортировать вашу библиотеку и объявить ее, после чего экземпляры будут перекрываться, даже если контекст будет проверен. Хуже того, не было бы разумного способа предпочесть одно другому.

16.05.2014
  • OverlappingInstances позволяет это, выбирая наиболее конкретный экземпляр. Иногда это полезно, но если бы вы также определили, скажем, instance Rational a => StatType a, это немедленно снова сломалось бы. 16.05.2014
  • Редко бывает хороший случай для использования OverlappingInstances, и это не один из таких случаев. 17.05.2014
  • Теперь это имеет смысл. Спасибо. 17.05.2014
  • Конечно, я немного опоздал на вечеринку, но @user2407038, можете ли вы рассказать об этом подробнее? 26.07.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..