1

文字データを追加するだけで、XML または JSON の存在を無視する API 統合に取り組んでいます。(興味がある場合は、 Metro2形式)

単純化していますが、人を次のようにシリアル化する必要があると想像してください。

  • At pos 0, 4 chars: メッセージのバイト数
  • 位置 5: 6 文字:"PERSON"ハードコーディング
  • 位置 11: 20 文字: 名前、左揃え、スペース埋め込み
  • 位置 21: 8 文字: 誕生日、YYYYMMDD
  • 29 番目の位置: 3 文字: 年齢、右寄せ、ゼロ詰め

数値フィールドは常に右揃えで、ゼロが埋め込まれます。テキスト フィールドは常に左揃えで、スペースが埋め込まれます。

例えば:

"0032PERSONDAVID WILCOX        19820711035"

これを型システムで表現できますか?サーヴァントのように?このようなもの?

newtype ByteLength = ByteLength Int
newtype Age = Age Int
-- etc

type PersonMessage
     = Field ByteLength '0
    :| Field "PERSON" '5
    :| Field Name '11
    :| Field Date '21
    :| Field Age '29

-- :| is a theoretical type operator, like :> in servant
-- the number is the expected offset
-- the length of the field is implicit in the type

シリアライゼーションの実装が型と一致することを静的に確認できますか?

Name3 番目のフィールド ( )のオフセットが であることを静的に確認できます11か? 前のフィールドの長さを合計すると 11 になりますか? 完全な依存型のサポートが必要になるように思われるので、私はノーだと思います。

これは正しい軌道に乗っていますか?

instance ToMetro Age where
   -- get the length into the type system using a type family?
   field = Numeric '3

   -- express how this is encoded. Would need to use the length from the type family. Or if that doesn't work, put it in the constructor.
   toMetro age = Numeric age

更新:静的に検証したい関数の例:

personToMetro :: Person -> PersonMessage
personToMetro p = error "Make sure that what I return is a PersonMessage"
4

1 に答える 1