haskell-jp / beginners #16 at 2021-07-08 19:32:41 +0900

1年前ぐらいから、lens恐怖症を克服してlensを使うようになりました。
makeFields でプレフィクス無しで参照できるのを便利に使っています。
しかし、取得時が楽になった分、これまで我慢していた構築時のプレフィクスも消せないかなと思えてしまいます。
添付したスニペットみたいに、構築時にもプレフィクスを取り除きたいです。

最近大量のデータ型をサンプル生成しなければいけなくて、強くそう思うようになりました。
とりあえずは雑なデータを入れて、変更したい場所だけをlensのSetterで変更するようにしていますが、雑に入れるわけにもいかないデータを構築するときや、そもそも構築の原点ではやはりプレフィクスを一々入れる必要があるので面倒です。
Stackageに載ってないGHCは流石に実運用するのがライブラリの構築など面倒なので、`NoFieldSelectors` を使ってプレフィクス自体を消すわけにもいきません。
lensなどを使ってプレフィクス無しで構築する方法は存在しますか?
すでにライブラリーがあるかは知りませんが、こういう :point_down: 使い方のものは作れるだろうな、と踏んでいます:
mkRecord @Color (field @"r" 0 :&: field @"g" 1 :&: field @"b" 2)

※各関数の名前は適当です
実装方法は、恐らくこんな :point_down: 感じ
data Field (s :: Symbol) (a :: Type) = Field a
-- ^ フィールドの名前と値のペア

class PrefixedRecord r where
  type NonPrefixedFields :: '[Field Symbol *]
  -- ^ この辺kindが合っているか自信がないですが、要するにプレフィックスを除いたフィールドと、値のペアを表すhetero list
  mkRecord :: [Field s a] -> r

-- 実装例
instance PrefixedRecord Color where
  type NonPrefixedFields = '[Field "r" Int, Field "g" Int, Field "b" Int]
  mkRecord = ...

恐らくコードは間違っているので雰囲気だけつかんでいただきたいのですが(singletonを作らないといけないはず)、要するに、プレフィックスを取り除いたフィールドを Field みたいな型で表現して、それのHListから構築できることを表す型クラスを作って、あとはそのインスタンスをTemplate HaskellなりGenericsなりで生成すればいけるのではないかと思います。
頑張って実装するのも手かなあと悩みましたが…
NoFieldSelectors が出るまでのつなぎでしか無いことを考えると実装を躊躇いますね…
:sorena: 結局、他のextensible recordと同じで、随分不格好な構文になってしまいますしね... :disappointed_relieved: