Spec-Zone.ru › Haskell 9

6.6.7. Вывод стратегий

DerivingStrategies
Since:

8.2.1

Status:

Включено в GHC2024

Разрешено несколько deriving, каждое из которых необязательно квалифицировано с помощью стратегии.

В большинстве случаев каждое deriving утверждение генерирует экземпляр типа класса однозначным способом. Однако существует частный случай, когда одновременное включение расширений GeneralizedNewtypeDeriving и DeriveAnyClass может сделать вывод неоднозначным. Рассмотрим следующий пример

{-# LANGUAGE DeriveAnyClass, GeneralizedNewtypeDeriving #-}
newtype Foo = MkFoo Bar deriving C

Можно выбрать либо DeriveAnyClass подход к выводу C, либо GeneralizedNewtypeDeriving подход к выводу C, оба из которых будут в равной степени верны. GHC по умолчанию отдаёт предпочтение DeriveAnyClass в таких спорах, но это не является удовлетворительным решением, поскольку это лишает пользователей возможности использовать оба расширения языка в одном модуле.

Чтобы сделать это более надёжным, GHC имеет понятие стратегий вывода, которые позволяют пользователю явно указать, какой подход использовать при выводе экземпляра. Для активации этой функции необходимо включить расширение языка DerivingStrategies. Стратегия вывода может быть указана в секции вывода

newtype Foo = MkFoo Bar
  deriving newtype C

Или в отдельном объявлении вывода

deriving anyclass instance C Foo

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

newtype Baz = Baz Quux
  deriving          (Eq, Ord)
  deriving stock    (Read, Show)
  deriving newtype  (Num, Floating)
  deriving anyclass C

В настоящее время доступны следующие стратегии вывода:

  • stock: Заставить GHC реализовать «стандартный» экземпляр для типа данных, если это возможно (например, Eq, Ord, Generic, Data, Functor, и т. д.)
  • anyclass: Использовать DeriveAnyClass (см. Вывод любого другого класса)
  • newtype: Use GeneralizedNewtypeDeriving

    (см. Обобщённые производные экземпляры для новых типов)

  • via: Использовать DerivingVia (см. Вывод через)

6.6.7.1. Стратегия вывода по умолчанию

Если явная стратегия вывода не указана, могут применяться несколько стратегий. В этом случае GHC выбирает стратегию следующим образом:

  1. Стандартные типы классов, то есть те, которые указаны в отчёте и те, которые включены расширениями языка языковых расширений, выводятся с помощью стратегии stock, с одним исключением:

    • Для новых типов Eq, Ord, Ix и Bounded всегда выводятся с помощью стратегии newtype, даже без включения GeneralizedNewtypeDeriving. (Не должно быть заметных различий с экземплярами, выведенными с помощью стандартной стратегии.)
    • Также для новых типов Functor, Foldable и Enum выводятся с помощью стратегии newtype при включённом GeneralizedNewtypeDeriving и успешном выводе.
  2. Для любого другого типа класса:

    1. При включении DeriveAnyClass используйте стратегию anyclass.
    2. При включении GeneralizedNewtypeDeriving и выводе для нового типа используйте стратегию newtype.

    Если оба правила применимы к секции вывода, то используется anyclass, и пользователю выдаётся предупреждение об неоднозначности. Предупреждение можно избежать, явно указав желаемую стратегию вывода.

© 2002–2007 The University Court of the University of Glasgow. All rights reserved.
Licensed under the Glasgow Haskell Compiler License.
https://downloads.haskell.org/~ghc/9.12.1/docs/users_guide/exts/deriving_strategies.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API