Как «применить» переменную типа в Template Haskell? - PullRequest
0 голосов
/ 22 октября 2018

Я передаю запись со следующей структурой функции Template Haskell:

module Editor.App where

data WithMaybe
data WithoutMaybe

type family TypeSelector a b where
  TypeSelector WithMaybe b = Maybe b
  TypeSelector WithoutMaybe b = b

data MyRecord a = MyRecord
  { field1 :: TypeSelector a Int
  , field2 :: TypeSelector a String
  }

$(myTHFunction ''MyRecord)

Внутри myTHFunction Я звоню reify, и она правильно дает мне следующий тип- Info:

TyConI 
  (DataD 
    []
    Editor.App.MyRecord 
    [KindedTV a_6989586621679348600 StarT] 
    Nothing 
    [RecC Editor.App.MyRecord 
      [ ( Editor.App.field1
        , Bang NoSourceUnpackedness NoSourceStrictness
        , AppT  (AppT (ConT Editor.App.TypeSelector) (VarT a_6989586621679348600)) 
                (ConT GHC.Types.Int) )
      , ( Editor.App.field2
        , Bang NoSourceUnpackedness NoSourceStrictness
        , AppT  (AppT (ConT Editor.App.TypeSelector) (VarT a_6989586621679348600)) 
                (ConT GHC.Base.String) )
      ]
    ] 
    []
  )

Однако в моей логике приложения я не могу перейти к непримененному KindedTV a_6989586621679348600 StarT.Итак, мой вопрос:

  • как мне "применить" эту переменную типа в TH
  • или как мне применить ее до передачи ееTH.Я пытался $(myTHFunction ''(MyRecord SomeSelector)), но это не работает.

1 Ответ

0 голосов
/ 22 октября 2018

Возможно, это два вопроса:

  1. Вы хотите знать, как подставить переменную свободного типа в тип.

    Лучший способ сделать это Iмы знаем, что нужно использовать applySubstitution из пакета th-abstraction, который также включает в себя нормализованные представления типов данных в версиях GHC, поэтому вы не привязываетесь к одной версии Template Haskell.

  2. Вы хотите знать, как передать прикладной тип, используя TH вместо одного имени.

    Синтаксис в кавычках - например, 'ValueName или ''TypeName - цитата имена , которые просто соответствуют ссылкам на привязки.MyRecord SomeSelector явно не имя, это тип.Следовательно, вы должны использовать синтаксис цитаты типа вместо синтаксиса цитаты имени, который написан [t|MyRecord SomeSelector|].Эта цитата даст вам значение типа Language.Haskell.TH.Syntax.Type, который является структурированным типом данных, который представляет собой AST произвольного типа Haskell.

Насколько язнаете, в какой-то библиотеке нет записанной функции, которая позволяла бы вам перейти непосредственно от Type с формой T X ... к расширенному списку конструкторов, связанных с T, с аргументами переменных, экземплярами которых были созданы типы X ...,Это, конечно, частичная функция: [t|forall a. a|] цитирует действительное Type, но оно не имеет форму T X ..., поэтому вам придется самостоятельно обрабатывать этот режим отказа (и, надеюсь, сообщить полезное сообщение об ошибке).Его можно определить в терминах applySubstitution без особых усилий, но вам придется немного унизиться, получая Type, чтобы получить правильную информацию.

...