Spec-Zone.ru › Haskell 9

6.5.4. Разрешение неоднозначностей полей записей

DisambiguateRecordFields
Since:

6.8.1

Implied by:

RecordWildCards, DuplicateRecordFields

Status:

Included in GHC2024

Позволяет компилятору автоматически выбирать между полями записей с одинаковыми именами (если выбор однозначен).

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

module M where
  data S = MkS { x :: Int, y :: Bool }

module Foo where
  import M

  data T = MkT { x :: Int }

  ok1 (MkS { x = n }) = n+1   -- Unambiguous
  ok2 n = MkT { x = n+1 }     -- Unambiguous

  bad1 k = k { x = 3 }        -- Ambiguous
  bad2 k = x k                -- Ambiguous

Несмотря на то, что в области видимости есть две x’ы, ясно, что x в шаблоне в определении ok1 может относиться только к полю x типа S. Аналогично для функции ok2. Однако в обновлении записи в bad1 и выборе записи в bad2 неясно, какой из двух типов подразумевается.

Haskell 98 считает все четыре случая неоднозначными, но с расширением DisambiguateRecordFields GHC будет принимать первые два. Правила точно такие же, как и для объявлений экземпляров в Haskell 98, где имена методов в левой части связываний методов в объявлении экземпляра однозначно ссылаются на метод этого класса (при условии, что они вообще находятся в области видимости), даже если в области видимости есть другие переменные с тем же именем. Это уменьшает громоздкость квалифицированных имён, когда вы импортируете две записи из разных модулей, использующих одно и то же имя поля.

Начиная с версии 9.2.1, поля записей в обновлениях разрешаются неоднозначно, игнорируя имена, которые не являются именами полей, в области видимости. Например, следующее принимается с расширением DisambiguateRecordFields:

module Bar where
  import M  -- imports the field x

  x = ()

  e r = r { x = 0 }  -- unambiguously refers to the field

Некоторые детали:

  • Разрешение неоднозначностей полей можно комбинировать с омонимией (см. Омонимия записей). Например:

    module Foo where
      import M
      x=True
      ok3 (MkS { x }) = x+1   -- Uses both disambiguation and punning
    
  • С расширением DisambiguateRecordFields вы можете использовать неквалифицированные имена полей, даже если соответствующий селектор находится в области видимости квалифицированным. Например, предположив тот же модуль M , что и в нашем предыдущем примере, это законно:

    module Foo where
      import qualified M    -- Note qualified
    
      ok4 (M.MkS { x = n }) = n+1   -- Unambiguous
    

    Так как конструктор MkS находится в области видимости только квалифицированным, вы должны назвать его M.MkS, но поле x не нужно квалифицировать, даже если M.x находится в области видимости, но x нет (по сути, оно квалифицируется конструктором).

© 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/disambiguate_record_fields.html

Spec-Zone.ru

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