[<<][haskell][>>][..]
Sat Jun 23 11:01:45 EDT 2018

Phantom types

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
data Tag_osd335_sm
data Tag_am335x_signal
data Tag_firmware

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
organized.

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.







[Reply][About]
[<<][haskell][>>][..]