1 -----------------------------------------------------------------------------
\r
2 -- $Id: OptTable.hs,v 1.1 1999/11/12 11:54:17 simonmar Exp $
\r
4 -- OGI_Table : Class for combinators used in building 2D tables.
\r
6 -- Copyright (c) 1999 Andy Gill
\r
8 -- This module is distributed as Open Source software under the
\r
9 -- Artistic License; see the file "Artistic" that is included
\r
10 -- in the distribution for details.
\r
11 -----------------------------------------------------------------------------
\r
14 OptTable, -- abstract
\r
21 import qualified ClassTable as TC
\r
23 instance TC.Table OptTable where
\r
24 single = OptTable.single
\r
25 beside = OptTable.beside
\r
26 above = OptTable.above
\r
27 getMatrix = OptTable.getMatrix
\r
29 instance (Show a) => Show (OptTable a) where
\r
30 showsPrec p = TC.showsTable
\r
32 type TableI a = [[(a,(Int,Int))]] -> [[(a,(Int,Int))]]
\r
34 data OptTable a = Table (Int -> Int -> TableI a) Int Int
\r
37 - Perhaps one day I'll fell adventureous, and write the Show instance
\r
38 - to show boxes aka the above ascii renditions.
\r
41 -- You can create a (1x1) table entry
\r
42 single :: a -> OptTable a
\r
43 single a = Table (\ x y z -> [(a,(x+1,y+1))] : z) 1 1
\r
45 -- You can compose tables, horizonally and vertically
\r
46 above :: OptTable a -> OptTable a -> OptTable a
\r
47 beside :: OptTable a -> OptTable a -> OptTable a
\r
49 t1 `above` t2 = trans (combine (trans t1) (trans t2) (.))
\r
51 t1 `beside` t2 = combine t1 t2 (\ lst1 lst2 r ->
\r
53 -- Note this depends on the fact that
\r
54 -- that the result has the same number
\r
55 -- of lines as the y dimention; one list
\r
56 -- per line. This is not true in general
\r
57 -- but is always true for these combinators.
\r
58 -- I should assert this!
\r
59 beside (x:xs) (y:ys) = (x ++ y) : beside xs ys
\r
60 beside (x:xs) [] = x : xs ++ r
\r
61 beside [] (y:ys) = y : ys ++ r
\r
64 beside (lst1 []) (lst2 []))
\r
66 -- trans flips (transposes) over the x and y axis of
\r
67 -- the table. It is only used internally, and typically
\r
68 -- in pairs, ie. (flip ... munge ... (un)flip).
\r
70 trans :: OptTable a -> OptTable a
\r
71 trans (Table f1 x1 y1) = Table (flip f1) y1 x1
\r
73 combine :: OptTable a
\r
75 -> (TableI a -> TableI b -> TableI c)
\r
77 combine (Table f1 x1 y1) (Table f2 x2 y2) comb = Table new_fn (x1+x2) max_y
\r
81 case compare y1 y2 of
\r
82 EQ -> comb (f1 0 y) (f2 x y)
\r
83 GT -> comb (f1 0 y) (f2 x (y + y1 - y2))
\r
84 LT -> comb (f1 0 (y + y2 - y1)) (f2 x y)
\r
86 -- This is the other thing you can do with a Table;
\r
87 -- turn it into a 2D list, tagged with the (x,y)
\r
88 -- sizes of each cell in the table.
\r
90 getMatrix :: OptTable a -> [[(a,(Int,Int))]]
\r
91 getMatrix (Table r _ _) = r 0 0 []
\r