module Utils.Table where
import Prelude hiding (map)
import Control.Monad
import qualified Data.List as L
import qualified Data.Map as Map
import Data.Function
type Table row col c = Map.Map (row,col) c
type Stripe a b = Map.Map a b
listTable lst = Map.fromList . concat $ [[((u,v),x) |x <- as | u <- [1..]] | as <- lst | v <- [1..]]
fromList x = Map.fromList x
toList x = Map.toList x
elems = Map.elems
indexes = Map.keys
intersectionWith :: (Ord row, Ord col) => (a -> b -> c)
-> Table row col a
-> Table row col b
-> Table row col c
intersectionWith = Map.intersectionWith
map f = Map.map f
mapM f = seqTable . map f
mapI f = Map.mapWithKey f
mapIM f = seqTable . mapI f
mapIM_ f = seqTable_ . mapI f
row :: (Ord a, Ord b) => a -> Table a b c -> Stripe b c
row rowName table = rows table Map.! rowName
column :: (Ord a, Ord b) => b -> Table a b c -> Stripe a c
column colName table = columns table Map.! colName
rows :: (Ord a, Ord b) => Table a b c -> Map.Map a (Stripe b c)
rows = getStripe (snd,fst)
columns :: (Ord a, Ord b) => Table a b c -> Map.Map b (Stripe a c)
columns = getStripe (fst,snd)
rowNames :: (Ord a, Ord b) => Table a b c -> [a]
rowNames = L.nub . L.map fst . Map.keys
colNames :: (Ord a, Ord b) => Table a b c -> [b]
colNames = L.nub . L.map snd . Map.keys
fromRows :: (Ord a, Ord b) => Map.Map a (Stripe b c) -> Table a b c
fromRows rs = Map.fromList
[((r,c),rs Map.! r Map.! c)
| r <- Map.keys rs
, c <- L.nub $ L.concatMap Map.keys $ Map.elems rs]
fromCols :: (Ord a, Ord b) => Map.Map a (Stripe b c) -> Table b a c
fromCols rs = Map.fromList
[((c,r),rs Map.! r Map.! c)
| r <- Map.keys rs
, c <- L.nub $ L.concatMap Map.keys $ Map.elems rs]
namedGroupsBy op = L.map (\x -> (op (head x),x))
. L.groupBy (\x y -> op x == op y)
. L.sortBy (compare `on` op)
getStripe (want,lose) table
= Map.fromList
. L.map makeStripe
. L.map dropR
. namedGroupsBy (\(k,_) -> lose k)
. Map.toList $ table
where
dropR (n,s) = (n,L.map (\(k,v) -> (want k,v)) s)
makeStripe (s,g) = (s,(Map.fromList g))
seqTable table = Control.Monad.mapM (\(k,v) -> v >>= \r-> return (k,r)) (Map.toList table)
>>= return . Map.fromList
seqTable_ table = Control.Monad.mapM_
(\(k,v) -> v) (Map.toList table)