1.15.1のDhallでInject, Interpretの型クラスインスタン...

1.15.1のDhallでInject, Interpretの型クラスインスタンスを定義した際に以下のように定義して、dhallファイルをパースしようとすると無限ループにはまるのですが、回避策などはありますか。

data Person = Person {
      pName :: !Text
    , pAge  :: !Natural
    } deriving (Eq, Show)

instance Interpret Person where
    autoWith _ = autoWith $ defaultInterpretOptions {fieldModifier = T.drop 1}

instance Inject Person where
    injectWith _ = injectWith $ defaultInterpretOptions {fieldModifier = T.drop 1}


Interpretなら以下の方法で定義すればいいんだけど、
http://hackage.haskell.org/package/dhall-1.15.1/docs/Dhall.html#t:RecordType

instance Interpret Person where
    autoWith _ = record $ 
        Person <$> field "name" strictText 
               <*> field "age" natural


Injectの場合、dhall-1.15.1ではdefaultInterpretOptionsを使う以外方法が見当たらないのです。

Replies

1.15.1のDhallでInject, Interpretの型クラスインスタンスを定義した際に以下のように定義して、dhallファイルをパースしようとすると無限ループにはまるのですが、回避策などはありますか。

data Person = Person {
      pName :: !Text
    , pAge  :: !Natural
    } deriving (Eq, Show)

instance Interpret Person where
    autoWith _ = autoWith $ defaultInterpretOptions {fieldModifier = T.drop 1}

instance Inject Person where
    injectWith _ = injectWith $ defaultInterpretOptions {fieldModifier = T.drop 1}


Interpretなら以下の方法で定義すればいいんだけど、
http://hackage.haskell.org/package/dhall-1.15.1/docs/Dhall.html#t:RecordType

instance Interpret Person where
    autoWith _ = record $ 
        Person <$> field "name" strictText 
               <*> field "age" natural


Injectの場合、dhall-1.15.1ではdefaultInterpretOptionsを使う以外方法が見当たらないのです。

InputType Person を自分で定義してあげないといけない予感?

ソースコードを見た限りそうなんですけど、レコード型のInputTypeを定義するサンプルコードが見当たらないんですよね。。
http://hackage.haskell.org/package/dhall-1.15.1/docs/src/Dhall.html#line-865

RecordLits 直接いじろうとしてもValueの肩が Exp Src X なのでうまく行きそうにないですね自前でレコードの Interpret インスタンス書いたときそれで詰まった気がします。現状レコードは柔軟に型定義できなさそうです

@U7155GPR9
ありがとうー
思いっきり裏技になりますが、以下の方法なら可能でした(多分やったら怒られそう)

data Person = Person {
      pName :: !Text
    , pAge  :: !Natural
    } deriving (Eq, Generic, Show)

-- 一旦Genericを用いてInjectのインスタンス定義
instance Inject Person

-- !?
class MyInject a where
    myInject :: InputType a

instance MyInject Person where
    myInject = injectWith $ defaultInterpretOptions {fieldModifier = T.drop 1}

> let p = Person "Hiroto" 29
> pretty $ embed myInject p
> "{ Name = "hiroto", Age = 29 }"

でもこれどう考えても冗長的なコードだし、aesonのように定義できる気がするんですよねー。。他のチャンネルでもきいてみます。

1.19.1だと(>*<)とか使って出来そう? http://hackage.haskell.org/package/dhall-1.19.1/docs/Dhall.html#v:-62--42--60-

1.19.1にするならDevOpsと要相談になりますねー。
いま作業してるプロジェクトは1.15.1がデフォルトのようです。

ちょっと勘違いしてたんですが、最初のコードが無限ループするのって、autoWithの中でautoWithを呼んでるからってだけではないですかね。autoWithのデフォルト定義 autoWith options = fmap (evalState (genericAutoWith options) 1) を貼り付けてoptionの所変えてやってみては?

やってみたんですけど、今度は型エラーでコンパイルができなくなりますね。同じ名前の関数を別からインポートする必要があるのかな。。

dhallは比較的まだ新しい言語だし、当時はInjectの型クラスインスタンスは定義できなかったというのも十分ありえると思います。あったとしても相当ややこしかったのかも?(少なくともチュートリアルにはサンプルコードはありませんでした

genericAutoWith optionsState Int (Type (Rep Person a))toRep Person a -> Person になるはずなんですけど通りませんかね

目を通してくれてありがとうー。
https://gist.github.com/HirotoShioi/69a63c11e0f73afe01f9182986c052a0
色々引っ張ってきてやっとできました!