Sat Jun 23 11:01:45 EDT 2018
I'm doing some work cross-referencing tables, and I would like to
type-tag them such that lookup functions are typed.
They are organized in a way that some tables do not have proper types.
E.g. a table can contain both (a,b) and (a,c).
How to tackle this? Best to make some kind of split at import time.
More specifically, I have a schematics netlist file:
(netname, [(component_name, pin_name)])
Basically, each component should have its own type, and each pin name
should have one type per component.
EDIT: Something like this:
-- Main phantom String type
newtype Tag t = Tag String
instance Show (Tag t) where show (Tag s) = s
-- Void tags for the phantom type
gw4_octavo_csv :: IO [(Tag Tag_osd335_sm, Tag Tag_am335x_signal, Tag Tag_firmware)]
gw4_octavo_csv = do
table <- readCSVFile "gw4_octavo.csv"
let table' = checkTable table
return $ map (\[o,s,f] -> (Tag o, Tag s, Tag f)) table'
EDIT: The above is straightforward. The real problem is in "level
mixing" for distinguishing between variants. There are some generic
patterns in Pins.hs
EDIT: It really helps to have local type signatures such as:
dt_offset :: T T_am335x_zcz -> T T_dt_offset
dt_offset = (flip lookup') (map (\(_,pin,offset,_) -> (pin,offset)) bbb_pins)
The implementation in this case is not so interesting: it does what it
needs to do to make it work, given the ad-hoc way the information is
So yes, doing it like this is a good idea, with remarks
- Use phantom types and void tags. This is easy enough to use and
provides the necessary typing with a little extra notation noise.
- Actual data types are only needed when sums are involved.
Implementing sums is where most of the work is (products are easy,
sums are hard).
- Implementing full sum types is probably too much work, so allow for
a "misc" alternative that captures the information, but doesn't
encode it at the type level. This allows to gradually refine.
- Use type annotations for all the converter functions. That is the
information needed to understand the program.