Emping-0.3: src/Codec.hs
module Codec ( avCod, avArr )where
{- module: code a table of attributes and values
Note: extended Haskell because of dependent parameters
first row of table: attribute names (must be unique)
following rows of table: attribute values
avArr produces an array of string lists
head of each list, with index 0, is an attribute name
tail of each list, starting with index 1, has value names
avCod produces a list of lists of attribute-value tuples
first of each tuple codes an attribute as an Int index
into the attribute-value array
second of each tuble codes a value as an index into the
list indexed by its attribute (0 is the attribute name,
and 1 is the first value in the list)
-}
import Data.List (transpose, elemIndex)
import Control.Monad.State
import Data.Array
-- get unique value-list and code strings as indices
-- Note: index incremented by 1, index 0 is the attribute
repl1 :: String -> [String] -> (Int, [String])
repl1 x tb = case elemIndex x tb of
Nothing -> ((length tb) + 1, tb ++ [x] )
Just i -> (i + 1, tb)
toState :: String -> State [String] Int
toState x = State (repl1 x)
getVals :: [String] -> ([Int],[String])
getVals x = (runState (getState x)) [] where
getState = sequence . (map toState)
getInds :: [String] -> [Int]
getInds = fst . getVals
getTb :: [String] -> [String]
getTb = snd . getVals
-- get attribute-value lists from the table
-- Note: see comment at start for indexing scheme
avLs :: [[String]] -> [[String]]
avLs [] = error "Codec avLs: empty String list"
avLs (_:[]) = error "Codec avLs : only one element in String list"
avLs (x:xs) = zipWith (:) x (values xs) where
values = (map getTb) . transpose
-- replace table, except first line, with:
-- tuples representing attribute-value pair
-- Note: see comment at start for indexing scheme
avCod :: [[String]] -> [[(Int, Int)]]
avCod [] = error "Codec avCod: empty String list"
avCod (_:[]) = error "Codec avCod : only one element in String list"
avCod ls = map (zip [0..]) (values (tail ls))
where values = transpose . (map getInds) . transpose
-- make an array of attribute-value lists from the
-- table, instead of a list of lists of Strings
avArr :: [[String]] -> Array Int [String]
avArr tb = listArray (0, (length attvals) -1) attvals where
attvals = avLs tb