Spec-Zone.ru › Haskell 9

6.5.1. Разрешение имён полей записей

Имя поля записи x можно использовать в четырёх контекстах:

  1. При создании записи: C{ x = 3 }
  2. При обновлении записи: r{ x = 4 }
  3. При сопоставлении с образцом записи: case r of C{ x = value } -> …
  4. Как отдельный селектор записи: x r

В этих четырёх случаях действуют следующие правила разрешения имён полей:

  1. Неквалифицированное имя «x» однозначно тогда и только тогда, когда в области видимости есть только одно неквалифицированное «x».
  2. Квалифицированное имя «M.x» однозначно тогда и только тогда, когда в области видимости есть только одно «M.x».

Эти правила дополняются следующими расширениями:

  • DisambiguateRecordFields: При создании записей и сопоставлении с образцом (C{ x = …}) неквалифицированное имя поля x однозначно тогда и только тогда, когда конструктор данных (C) содержит поле x и это поле находится в области видимости без квалификатора либо с квалификатором Q.x, независимо от Q. Аналогично, при создании записей и сопоставлении с образцом квалифицированное имя поля M.x однозначно тогда и только тогда, когда конструктор данных (C) содержит поле x и это поле находится в области видимости с квалификатором M.x.

    При обновлении записей (r{ x = 3 }) имя поля x однозначно тогда и только тогда, когда в области видимости есть только одно неквалифицированное имя поля x. Аналогично, обновление записи с квалифицированным полем r{ M.x = 3 } однозначно, если только одно имя поля находится в области видимости как M.x. В обоих случаях имена, не являющиеся именами полей, игнорируются.

  • DuplicateRecordFields: Это расширение разрешает обновление записей, если ровно один тип содержит все обновляемые поля, даже если согласно двум приведённым выше правилам разрешения имён полей каждое из них по отдельности неоднозначно.

    Например:

    data S = MkS1 { x :: Int, y :: Bool }
           | MkS2 { x :: Int }
    
    data T = MkT1 { x :: Int, z :: Bool }
           | MkT2 { z :: Bool }
    
    f r = r{ x=3, y=True }
    

Единственный тип данных, у которого полями являются и x, и y, — это S, поэтому имена полей x и y однозначно относятся к типу данных S.

  • NoFieldSelectors: При включённом этом расширении имена селекторов полей в области видимости игнорируются в контексте выражения.

    Например:

    data T = MkT { x :: Int }
    
    x :: String
    x = "Hello"
    
    f = x
    

При NoFieldSelectors выражение x в правой части f относится к x :: String, а не к полю 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/record_field_resolution.html

Spec-Zone.ru

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