Open ocramz opened 5 years ago
generate CSV header from the type with generics-sop metadata
After a fair bit of trial and error, header
produces a
simple representation of an arbitrary type which can be pretty-printed
as a tree :
data A = MkA Int deriving (Eq, Show, G.Generic, Heidi)
data B = MkB Int Char deriving (Eq, Show, G.Generic, Heidi)
data B2 = MkB2 { b21 :: Int, b22 :: Char } deriving (Eq, Show, G.Generic, Heidi)
data C = MkC1 {c1 :: Int} | MkC2 A | MkC3 () deriving (Eq, Show, G.Generic, Heidi)
data R = MkR { r1 :: B2, r2 :: C , r3 :: B } deriving (Eq, Show, G.Generic, Heidi)
λ> printBox $ headerBox $ header (Proxy @R)
R
------------------------------------------------
MkR
R
------------*------------*----------------------
r1 | r3 | r2
B2 B C
---------- ---------- ------+------+------
MkB2 MkB MkC3 | MkC1 | MkC2
B2 B () Int A
----*----- ----*----- ---
b21 | b22 _0 | _1 MkA
Int Char Int Char Int
In case someone else wants to move this forward, my thinking so far is as follows:
header
computes a rose tree representation of a type, and only requires a Generic
and an empty instance of HasHeader
(populated automatically via the Generic instance) (see https://github.com/ocramz/heidi/blob/master/src/Core/Data/Frame/PrettyPrint.hs#L152 )encode
uses the generic representation of a value and produces a corresponding representation; values however (i.e. data rows) are "flattened" from rose trees into one-level deep tries, keyed by lists of elements (https://github.com/ocramz/heidi/blob/master/src/Data/Generics/Encode/Internal.hs#L101). This flat representation makes lookup and traversal convenient. A heidi
dataframe is produced by encode
ing all values in a list.header
are convenient for pretty-printing the sum-of-products structure of general Haskell ADTs, as seen above (implementation at https://github.com/ocramz/heidi/blob/master/src/Core/Data/Frame/PrettyPrint.hs#L91 )header
contain all possible combination of keys that might appear in encode
d values, which is why Header
values can be used in the Show instance of an encode
d dataframe:
Header
keys and render in the corresponding column, under the header
e.g.
ascii
:https://hackage.haskell.org/package/colonnade-1.2.0.1/docs/Colonnade.html#g:10