Spec-Zone.ru › Haskell 9

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

DisambiguateRecordFields
С версии:

6.8.1

Подразумевается расширением:

RecordWildCards, DuplicateRecordFields

Статус:

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

Spec-Zone.ru

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