Имя шаблона Haskell цитирует desugar 'x для NameG?

Могу ли я всегда ожидать, что синтаксис с одинарной одинарной кавычкой обессуглит конструктор NameG? например делает

'x

всегда обессахаривать

(Name (OccName "x") (NameG VarName (PkgName "some-package") (ModName "SomeModule")))

Эта информация всегда должна быть там, после разрешения имени, после которого запускается Template Haskell, верно? И я не смог процитировать местные имена, хотя меня интересует только цитирование имен верхнего уровня.

Контекст: я хочу написать функцию, которая возвращает уникальный идентификатор. Это частичная функция, потому что я не могу ограничивать ввод, так как Template Haskell не имеет никаких GADT или чего-то еще, а я не хочу оборачивать вывод в неопределенность. И я не хочу использовать квази-кавычки или склейки, если подойдет '. Я хочу доказать, что эта частичная функция безопасна во время выполнения при использовании, как указано выше, цитируя имена верхнего уровня в том же модуле, учитывая:

name (Name occ (NameG _ pkg mod)) = Unique occ pkg mod

Я хочу иметь функцию вроде:

(<=>) :: Name -> a -> Named a

данный:

data Named a = Named a Unique

для аннотирования привязок переменных:

x = 'x
 <=> ...

без необходимости пользователю использовать тяжелый синтаксис сплайсинга $(name ...) и вызывать сплайсинг во время компиляции:

x = $(name 'x)
 <=> ...

Пользователь будет писать их много для настройки.

https://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/template-haskell.html и https://hackage.haskell.org/package/template-haskell-2.8.0.0/docs/src/Language-Haskell-TH-Syntax.html#Name не сказал.

(p.s. Я также хотел бы знать, имеет ли синтаксис двойной одинарной кавычки (например, ''T) аналогичную гарантию, хотя я ожидаю, что они будут одинаковыми).


person sam boosalis    schedule 11.01.2015    source источник
comment
let x = () in $(stringE $ Data.Generics.gshow 'x) оценивается как "(Name (OccName \"x\") (NameL (1627422417)))"   -  person aavogt    schedule 13.01.2015


Ответы (1)


Поскольку ' имена в кавычках известны во время компиляции, почему бы вам не изменить имя, чтобы оно было в монаде Q:

name :: Name -> ExpQ
name (Name occ (NameG _ pkg mod)) = [| Unique occ pkg mod |]
name n = fail $ "invalid name: "++ gshow n

Затем вы используете $(name 'show) :: Unique вместо name 'show :: Unique. Если вы получите неверный Name (скажем, кто-то использует mkName), этот сбой проявится во время компиляции.

person aavogt    schedule 13.01.2015
comment
да, это мой план Б, это безопаснее, но уродливее (и, возможно, медленнее во время компиляции). Я отредактировал вопрос. - person sam boosalis; 13.01.2015