Spec-Zone.ru › Haskell 9

6.6.7. Стратегии вывода

DerivingStrategies
Начиная с:

8.2.1

Статус:

Включено в 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.14.1/docs/users_guide/exts/deriving_strategies.html

Spec-Zone.ru

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