2014-02-12 4 views
6

Я понимаю, как использовать синтаксис записи в Haskell, но мне трудно понять, что вещь внутри фигурных фигурных скобок is.Синтаксис записи Haskell desugared

data PairRecord = PR {foo::Int, bar::String} deriving (Eq,Show) 
x = (PR {foo=1, bar="init"}) 
y= x {foo=23} 
  • Что является это {foo=23} вещь? Последняя строка выглядит так, как если бы это был аргумент функции x, что явно не так.
  • Есть ли что-нибудь еще, что я могу сделать с {foo=23}, за исключением размещения его прямо за a запись?
  • Есть ли формальный способ обесцвечивать его, как то, что мы можем сделать с помощью do нотации?

ответ

10

Этот синтаксис называется «обновление записи» или «обновление с использованием меток полей» и описан в Section 3.15.3 of the Haskell 2010 report. Его можно отпустить. Точные правила приведены в отчете. В вашем примере, desugaring из x {foo = 23} является

case x of 
    PR f b -> PR 23 b 
    _  -> error "Update error" 

Обратите внимание, что отчет использует вспомогательную функцию, называемую «выбрать» в desugaring, который описал в section before, 3.15.2, on "Construction using field labels".

+0

Значит, вы можете desugar x {foo = 23}, но {foo = 23} само по себе не имеет значения, и единственное использование связано с x (или другой записью) в нем? –

+1

Да, это так. Синтаксис '{foo = ...}' может использоваться только в конструкции, совпадении шаблонов или обновлении записи и только в сочетании с другими компонентами. Он не имеет смысла в изоляции. – kosmikus

0

Что вам нужно, это lenses. Но, во-первых, вы должны установить пакетный объектив.

+1

О, боже, это линзы, превращающиеся в jQuery Haskell? – Tarmil

+0

Насколько мне нравится линзы, это действительно не касается того, что задают. Это может сделать хорошую заметку, но это не отвечает на вопрос. –

+0

@Tarmil: Это действительно далека от этого ... –

0

, глядя на типы:

:t PR 
PR :: Int -> String -> PairRecord 

так это означает, что вам нужно Int и String, для того, чтобы построить PairRecord.

Теперь, в определении PairRecord, вы определили сбрую:

:t foo 
foo :: PairRecord -> Int 

для того, чтобы использовать Foo (как аксессор), вам нужно поставить PairRecord. Вы получает Int в качестве возвращаемого значения:

foo y 
23 

Это означает, как хорошо Foo в одиночку не имеет никакого значения, эта функция нужна PairRecord.

Как kosmikus уже указывают, синтаксис

y= x {foo=23} 

создает у из существующего PairRecord с целым числом равным 23 (с помощью функции доступа).

+0

foo *. * Имеет четко определенное значение: это функция от PairRecord до Int. Тем не менее, {foo = 23} не имеет ничего общего с x, если он есть. –

Смежные вопросы