Spec-Zone.ru › Haskell 9

6.5.11. Перегруженное обновление записи

OverloadedRecordUpdate
Начиная с:

9.2.0

Предоставляет синтаксис записей . при обновлении записей, например x{foo.bar = 1}.

ЭКСПЕРИМЕНТАЛЬНО Дизайн этого расширения может измениться в будущем. Пока не рекомендуется использовать это расширение в библиотеках с длительным сроком поддержки.

Обычно (но не обязательно) это расширение используют вместе с Перегруженная точка записи.

Пример:

{-# LANGUAGE AllowAmbiguousTypes, FunctionalDependencies, ScopedTypeVariables, PolyKinds, TypeApplications, DataKinds, FlexibleInstances #-}
{-# LANGUAGE NamedFieldPuns, RecordWildCards #-}
{-# LANGUAGE OverloadedRecordDot, OverloadedRecordUpdate, RebindableSyntax #-}

import Prelude

class HasField x r a | x r -> a where
  hasField :: r -> (a -> r, a)

getField :: forall x r a . HasField x r a => r -> a
getField = snd . hasField @x -- Note: a.x = is getField @"x" a.
setField :: forall x r a . HasField x r a => a -> r -> r
setField b a = fst (hasField @x a) b -- Note : a{x = b} is setField @"x" b a.

data Person = Person { name :: String } deriving Show
instance HasField "name" Person String where
    hasField r = (\x -> case r of Person { .. } -> Person { name = x, .. }, name r)

data Company = Company { company :: String, owner :: Person } deriving Show
instance HasField "company" Company String where
    hasField r = (\x -> case r of Company { .. } -> Company { company = x, .. }, company r)
instance HasField "owner" Company Person where
    hasField r = (\x -> case r of Company { .. } -> Company { owner = x, .. }, owner r)

main = do
  let c = Company {company = "Acme Corp.", owner = Person { name = "Wile E. Coyote" }}

  -- Top-level update
  print $ c{company = "Acme United"} -- Company {company = "Acme United", owner = Person {name = "Wile E. Coyote"}}

  -- Nested update
  print $ c{owner.name = "Walter C. Johnsen"} -- Company {company = "Acme Corp.", owner = Person {name = "Walter C. Johnsen"}}

  -- Punned update
  let name = "Walter C. Johnsen"
  print $ c{owner.name}  -- Company {company = "Acme Corp.", owner = Person {name = "Walter C. Johnsen"}}

OverloadedRecordUpdate работает, преобразуя выражения обновления записей . в выражения с использованием функций setField и getField. Обратите внимание, что все выражения обновления записей будут преобразованы в выражения setField независимо от того, используют они нотацию . или нет.

В настоящее время RebindableSyntax необходимо включать вместе с OverloadedRecordUpdate, а пользователи должны предоставлять определения для getField и setField. Мы ожидаем, что в будущей версии GHC это ограничение будет снято благодаря встроенной поддержке setField.

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

Spec-Zone.ru

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