文字データを追加するだけで、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
シリアライゼーションの実装が型と一致することを静的に確認できますか?
Name
3 番目のフィールド ( )のオフセットが であることを静的に確認できます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"