    {-# LANGUAGE DerivingStrategies         #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE LambdaCase                 #-}
    {- |
    Module      : Text.GridTable.ArrayTable
    Copyright   : © 2022-2023 Posit Software, PBC
    License     : MIT
    Maintainer  : Albert Krewinkel <albert@zeitkraut.de>

    Grid table representation based on arrays.
    -}

    module Text.GridTable.ArrayTable
      ( ArrayTable (..)
      , GridCell (..)
      , RowSpan (..)
      , ColSpan (..)
      , CellIndex
      , RowIndex (..)
      , ColIndex (..)
      , Alignment (..)
      , mapCells
      ) where

    import Data.Array (Array, Ix)
    import Data.Array.MArray (mapArray, thaw)
    import Data.Array.ST (runSTArray)

    -- | Table representation based on an array; cells are placed on a grid,
    -- with indices spanned by other cells containing placeholder cells that
    -- point to the spanning cell.
    data ArrayTable a = ArrayTable
      { forall a. ArrayTable a -> Array CellIndex (GridCell a)
    arrayTableCells    :: Array CellIndex (GridCell a)
      , forall a. ArrayTable a -> Maybe RowIndex
    arrayTableHead     :: Maybe RowIndex
      , forall a. ArrayTable a -> Maybe RowIndex
    arrayTableFoot     :: Maybe RowIndex
      , forall a. ArrayTable a -> Array ColIndex (Alignment, Int)
    arrayTableColSpecs :: Array ColIndex (Alignment, Int)
      }
      deriving stock (ArrayTable a -> ArrayTable a -> Bool
    (ArrayTable a -> ArrayTable a -> Bool)
    -> (ArrayTable a -> ArrayTable a -> Bool) -> Eq (ArrayTable a)
    forall a. Eq a => ArrayTable a -> ArrayTable a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => ArrayTable a -> ArrayTable a -> Bool
    == :: ArrayTable a -> ArrayTable a -> Bool
    $c/= :: forall a. Eq a => ArrayTable a -> ArrayTable a -> Bool
    /= :: ArrayTable a -> ArrayTable a -> Bool
    Eq, Int -> ArrayTable a -> ShowS
    [ArrayTable a] -> ShowS
    ArrayTable a -> String
    (Int -> ArrayTable a -> ShowS)
    -> (ArrayTable a -> String)
    -> ([ArrayTable a] -> ShowS)
    -> Show (ArrayTable a)
    forall a. Show a => Int -> ArrayTable a -> ShowS
    forall a. Show a => [ArrayTable a] -> ShowS
    forall a. Show a => ArrayTable a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> ArrayTable a -> ShowS
    showsPrec :: Int -> ArrayTable a -> ShowS
    $cshow :: forall a. Show a => ArrayTable a -> String
    show :: ArrayTable a -> String
    $cshowList :: forall a. Show a => [ArrayTable a] -> ShowS
    showList :: [ArrayTable a] -> ShowS
    Show)

    -- | Apply a function to all cell contents in a grid table.
    mapCells :: (a -> b) -> ArrayTable a -> ArrayTable b
    mapCells :: forall a b. (a -> b) -> ArrayTable a -> ArrayTable b
    mapCells a -> b
    f ArrayTable a
    gt =
      let f' :: GridCell a -> GridCell b
    f' = \case
            ContentCell RowSpan
    rs ColSpan
    cs a
    c  -> RowSpan -> ColSpan -> b -> GridCell b
    forall a. RowSpan -> ColSpan -> a -> GridCell a
    ContentCell RowSpan
    rs ColSpan
    cs (b -> GridCell b) -> b -> GridCell b
    forall a b. (a -> b) -> a -> b
    $ a -> b
    f a
    c
            ContinuationCell CellIndex
    idx -> CellIndex -> GridCell b
    forall a. CellIndex -> GridCell a
    ContinuationCell CellIndex
    idx
          cellArray :: Array CellIndex (GridCell b)
    cellArray = (forall s. ST s (STArray s CellIndex (GridCell b)))
    -> Array CellIndex (GridCell b)
    forall i e. (forall s. ST s (STArray s i e)) -> Array i e
    runSTArray ((forall s. ST s (STArray s CellIndex (GridCell b)))
     -> Array CellIndex (GridCell b))
    -> (forall s. ST s (STArray s CellIndex (GridCell b)))
    -> Array CellIndex (GridCell b)
    forall a b. (a -> b) -> a -> b
    $ do
            mut <- Array CellIndex (GridCell a)
    -> ST s (STArray s CellIndex (GridCell a))
    forall i (a :: * -> * -> *) e (b :: * -> * -> *) (m :: * -> *).
    (Ix i, IArray a e, MArray b e m) =>
    a i e -> m (b i e)
    thaw (Array CellIndex (GridCell a)
     -> ST s (STArray s CellIndex (GridCell a)))
    -> Array CellIndex (GridCell a)
    -> ST s (STArray s CellIndex (GridCell a))
    forall a b. (a -> b) -> a -> b
    $ ArrayTable a -> Array CellIndex (GridCell a)
    forall a. ArrayTable a -> Array CellIndex (GridCell a)
    arrayTableCells ArrayTable a
    gt
            mapArray f' mut
      in ArrayTable a
    gt { arrayTableCells = cellArray }

    -- | Row index in a table array.
    newtype RowIndex = RowIndex { RowIndex -> Int
    fromRowIndex :: Int }
      deriving stock (RowIndex -> RowIndex -> Bool
    (RowIndex -> RowIndex -> Bool)
    -> (RowIndex -> RowIndex -> Bool) -> Eq RowIndex
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: RowIndex -> RowIndex -> Bool
    == :: RowIndex -> RowIndex -> Bool
    $c/= :: RowIndex -> RowIndex -> Bool
    /= :: RowIndex -> RowIndex -> Bool
    Eq, Ord RowIndex
    Ord RowIndex =>
    ((RowIndex, RowIndex) -> [RowIndex])
    -> ((RowIndex, RowIndex) -> RowIndex -> Int)
    -> ((RowIndex, RowIndex) -> RowIndex -> Int)
    -> ((RowIndex, RowIndex) -> RowIndex -> Bool)
    -> ((RowIndex, RowIndex) -> Int)
    -> ((RowIndex, RowIndex) -> Int)
    -> Ix RowIndex
    (RowIndex, RowIndex) -> Int
    (RowIndex, RowIndex) -> [RowIndex]
    (RowIndex, RowIndex) -> RowIndex -> Bool
    (RowIndex, RowIndex) -> RowIndex -> Int
    forall a.
    Ord a =>
    ((a, a) -> [a])
    -> ((a, a) -> a -> Int)
    -> ((a, a) -> a -> Int)
    -> ((a, a) -> a -> Bool)
    -> ((a, a) -> Int)
    -> ((a, a) -> Int)
    -> Ix a
    $crange :: (RowIndex, RowIndex) -> [RowIndex]
    range :: (RowIndex, RowIndex) -> [RowIndex]
    $cindex :: (RowIndex, RowIndex) -> RowIndex -> Int
    index :: (RowIndex, RowIndex) -> RowIndex -> Int
    $cunsafeIndex :: (RowIndex, RowIndex) -> RowIndex -> Int
    unsafeIndex :: (RowIndex, RowIndex) -> RowIndex -> Int
    $cinRange :: (RowIndex, RowIndex) -> RowIndex -> Bool
    inRange :: (RowIndex, RowIndex) -> RowIndex -> Bool
    $crangeSize :: (RowIndex, RowIndex) -> Int
    rangeSize :: (RowIndex, RowIndex) -> Int
    $cunsafeRangeSize :: (RowIndex, RowIndex) -> Int
    unsafeRangeSize :: (RowIndex, RowIndex) -> Int
    Ix, Eq RowIndex
    Eq RowIndex =>
    (RowIndex -> RowIndex -> Ordering)
    -> (RowIndex -> RowIndex -> Bool)
    -> (RowIndex -> RowIndex -> Bool)
    -> (RowIndex -> RowIndex -> Bool)
    -> (RowIndex -> RowIndex -> Bool)
    -> (RowIndex -> RowIndex -> RowIndex)
    -> (RowIndex -> RowIndex -> RowIndex)
    -> Ord RowIndex
    RowIndex -> RowIndex -> Bool
    RowIndex -> RowIndex -> Ordering
    RowIndex -> RowIndex -> RowIndex
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: RowIndex -> RowIndex -> Ordering
    compare :: RowIndex -> RowIndex -> Ordering
    $c< :: RowIndex -> RowIndex -> Bool
    < :: RowIndex -> RowIndex -> Bool
    $c<= :: RowIndex -> RowIndex -> Bool
    <= :: RowIndex -> RowIndex -> Bool
    $c> :: RowIndex -> RowIndex -> Bool
    > :: RowIndex -> RowIndex -> Bool
    $c>= :: RowIndex -> RowIndex -> Bool
    >= :: RowIndex -> RowIndex -> Bool
    $cmax :: RowIndex -> RowIndex -> RowIndex
    max :: RowIndex -> RowIndex -> RowIndex
    $cmin :: RowIndex -> RowIndex -> RowIndex
    min :: RowIndex -> RowIndex -> RowIndex
    Ord)
      deriving newtype (Int -> RowIndex
    RowIndex -> Int
    RowIndex -> [RowIndex]
    RowIndex -> RowIndex
    RowIndex -> RowIndex -> [RowIndex]
    RowIndex -> RowIndex -> RowIndex -> [RowIndex]
    (RowIndex -> RowIndex)
    -> (RowIndex -> RowIndex)
    -> (Int -> RowIndex)
    -> (RowIndex -> Int)
    -> (RowIndex -> [RowIndex])
    -> (RowIndex -> RowIndex -> [RowIndex])
    -> (RowIndex -> RowIndex -> [RowIndex])
    -> (RowIndex -> RowIndex -> RowIndex -> [RowIndex])
    -> Enum RowIndex
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: RowIndex -> RowIndex
    succ :: RowIndex -> RowIndex
    $cpred :: RowIndex -> RowIndex
    pred :: RowIndex -> RowIndex
    $ctoEnum :: Int -> RowIndex
    toEnum :: Int -> RowIndex
    $cfromEnum :: RowIndex -> Int
    fromEnum :: RowIndex -> Int
    $cenumFrom :: RowIndex -> [RowIndex]
    enumFrom :: RowIndex -> [RowIndex]
    $cenumFromThen :: RowIndex -> RowIndex -> [RowIndex]
    enumFromThen :: RowIndex -> RowIndex -> [RowIndex]
    $cenumFromTo :: RowIndex -> RowIndex -> [RowIndex]
    enumFromTo :: RowIndex -> RowIndex -> [RowIndex]
    $cenumFromThenTo :: RowIndex -> RowIndex -> RowIndex -> [RowIndex]
    enumFromThenTo :: RowIndex -> RowIndex -> RowIndex -> [RowIndex]
    Enum, Integer -> RowIndex
    RowIndex -> RowIndex
    RowIndex -> RowIndex -> RowIndex
    (RowIndex -> RowIndex -> RowIndex)
    -> (RowIndex -> RowIndex -> RowIndex)
    -> (RowIndex -> RowIndex -> RowIndex)
    -> (RowIndex -> RowIndex)
    -> (RowIndex -> RowIndex)
    -> (RowIndex -> RowIndex)
    -> (Integer -> RowIndex)
    -> Num RowIndex
    forall a.
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (Integer -> a)
    -> Num a
    $c+ :: RowIndex -> RowIndex -> RowIndex
    + :: RowIndex -> RowIndex -> RowIndex
    $c- :: RowIndex -> RowIndex -> RowIndex
    - :: RowIndex -> RowIndex -> RowIndex
    $c* :: RowIndex -> RowIndex -> RowIndex
    * :: RowIndex -> RowIndex -> RowIndex
    $cnegate :: RowIndex -> RowIndex
    negate :: RowIndex -> RowIndex
    $cabs :: RowIndex -> RowIndex
    abs :: RowIndex -> RowIndex
    $csignum :: RowIndex -> RowIndex
    signum :: RowIndex -> RowIndex
    $cfromInteger :: Integer -> RowIndex
    fromInteger :: Integer -> RowIndex
    Num, Int -> RowIndex -> ShowS
    [RowIndex] -> ShowS
    RowIndex -> String
    (Int -> RowIndex -> ShowS)
    -> (RowIndex -> String) -> ([RowIndex] -> ShowS) -> Show RowIndex
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> RowIndex -> ShowS
    showsPrec :: Int -> RowIndex -> ShowS
    $cshow :: RowIndex -> String
    show :: RowIndex -> String
    $cshowList :: [RowIndex] -> ShowS
    showList :: [RowIndex] -> ShowS
    Show)

    -- | Column index in a table array.
    newtype ColIndex = ColIndex { ColIndex -> Int
    fromColIndex :: Int }
      deriving stock (ColIndex -> ColIndex -> Bool
    (ColIndex -> ColIndex -> Bool)
    -> (ColIndex -> ColIndex -> Bool) -> Eq ColIndex
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ColIndex -> ColIndex -> Bool
    == :: ColIndex -> ColIndex -> Bool
    $c/= :: ColIndex -> ColIndex -> Bool
    /= :: ColIndex -> ColIndex -> Bool
    Eq, Ord ColIndex
    Ord ColIndex =>
    ((ColIndex, ColIndex) -> [ColIndex])
    -> ((ColIndex, ColIndex) -> ColIndex -> Int)
    -> ((ColIndex, ColIndex) -> ColIndex -> Int)
    -> ((ColIndex, ColIndex) -> ColIndex -> Bool)
    -> ((ColIndex, ColIndex) -> Int)
    -> ((ColIndex, ColIndex) -> Int)
    -> Ix ColIndex
    (ColIndex, ColIndex) -> Int
    (ColIndex, ColIndex) -> [ColIndex]
    (ColIndex, ColIndex) -> ColIndex -> Bool
    (ColIndex, ColIndex) -> ColIndex -> Int
    forall a.
    Ord a =>
    ((a, a) -> [a])
    -> ((a, a) -> a -> Int)
    -> ((a, a) -> a -> Int)
    -> ((a, a) -> a -> Bool)
    -> ((a, a) -> Int)
    -> ((a, a) -> Int)
    -> Ix a
    $crange :: (ColIndex, ColIndex) -> [ColIndex]
    range :: (ColIndex, ColIndex) -> [ColIndex]
    $cindex :: (ColIndex, ColIndex) -> ColIndex -> Int
    index :: (ColIndex, ColIndex) -> ColIndex -> Int
    $cunsafeIndex :: (ColIndex, ColIndex) -> ColIndex -> Int
    unsafeIndex :: (ColIndex, ColIndex) -> ColIndex -> Int
    $cinRange :: (ColIndex, ColIndex) -> ColIndex -> Bool
    inRange :: (ColIndex, ColIndex) -> ColIndex -> Bool
    $crangeSize :: (ColIndex, ColIndex) -> Int
    rangeSize :: (ColIndex, ColIndex) -> Int
    $cunsafeRangeSize :: (ColIndex, ColIndex) -> Int
    unsafeRangeSize :: (ColIndex, ColIndex) -> Int
    Ix, Eq ColIndex
    Eq ColIndex =>
    (ColIndex -> ColIndex -> Ordering)
    -> (ColIndex -> ColIndex -> Bool)
    -> (ColIndex -> ColIndex -> Bool)
    -> (ColIndex -> ColIndex -> Bool)
    -> (ColIndex -> ColIndex -> Bool)
    -> (ColIndex -> ColIndex -> ColIndex)
    -> (ColIndex -> ColIndex -> ColIndex)
    -> Ord ColIndex
    ColIndex -> ColIndex -> Bool
    ColIndex -> ColIndex -> Ordering
    ColIndex -> ColIndex -> ColIndex
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ColIndex -> ColIndex -> Ordering
    compare :: ColIndex -> ColIndex -> Ordering
    $c< :: ColIndex -> ColIndex -> Bool
    < :: ColIndex -> ColIndex -> Bool
    $c<= :: ColIndex -> ColIndex -> Bool
    <= :: ColIndex -> ColIndex -> Bool
    $c> :: ColIndex -> ColIndex -> Bool
    > :: ColIndex -> ColIndex -> Bool
    $c>= :: ColIndex -> ColIndex -> Bool
    >= :: ColIndex -> ColIndex -> Bool
    $cmax :: ColIndex -> ColIndex -> ColIndex
    max :: ColIndex -> ColIndex -> ColIndex
    $cmin :: ColIndex -> ColIndex -> ColIndex
    min :: ColIndex -> ColIndex -> ColIndex
    Ord)
      deriving newtype (Int -> ColIndex
    ColIndex -> Int
    ColIndex -> [ColIndex]
    ColIndex -> ColIndex
    ColIndex -> ColIndex -> [ColIndex]
    ColIndex -> ColIndex -> ColIndex -> [ColIndex]
    (ColIndex -> ColIndex)
    -> (ColIndex -> ColIndex)
    -> (Int -> ColIndex)
    -> (ColIndex -> Int)
    -> (ColIndex -> [ColIndex])
    -> (ColIndex -> ColIndex -> [ColIndex])
    -> (ColIndex -> ColIndex -> [ColIndex])
    -> (ColIndex -> ColIndex -> ColIndex -> [ColIndex])
    -> Enum ColIndex
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: ColIndex -> ColIndex
    succ :: ColIndex -> ColIndex
    $cpred :: ColIndex -> ColIndex
    pred :: ColIndex -> ColIndex
    $ctoEnum :: Int -> ColIndex
    toEnum :: Int -> ColIndex
    $cfromEnum :: ColIndex -> Int
    fromEnum :: ColIndex -> Int
    $cenumFrom :: ColIndex -> [ColIndex]
    enumFrom :: ColIndex -> [ColIndex]
    $cenumFromThen :: ColIndex -> ColIndex -> [ColIndex]
    enumFromThen :: ColIndex -> ColIndex -> [ColIndex]
    $cenumFromTo :: ColIndex -> ColIndex -> [ColIndex]
    enumFromTo :: ColIndex -> ColIndex -> [ColIndex]
    $cenumFromThenTo :: ColIndex -> ColIndex -> ColIndex -> [ColIndex]
    enumFromThenTo :: ColIndex -> ColIndex -> ColIndex -> [ColIndex]
    Enum, Integer -> ColIndex
    ColIndex -> ColIndex
    ColIndex -> ColIndex -> ColIndex
    (ColIndex -> ColIndex -> ColIndex)
    -> (ColIndex -> ColIndex -> ColIndex)
    -> (ColIndex -> ColIndex -> ColIndex)
    -> (ColIndex -> ColIndex)
    -> (ColIndex -> ColIndex)
    -> (ColIndex -> ColIndex)
    -> (Integer -> ColIndex)
    -> Num ColIndex
    forall a.
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (Integer -> a)
    -> Num a
    $c+ :: ColIndex -> ColIndex -> ColIndex
    + :: ColIndex -> ColIndex -> ColIndex
    $c- :: ColIndex -> ColIndex -> ColIndex
    - :: ColIndex -> ColIndex -> ColIndex
    $c* :: ColIndex -> ColIndex -> ColIndex
    * :: ColIndex -> ColIndex -> ColIndex
    $cnegate :: ColIndex -> ColIndex
    negate :: ColIndex -> ColIndex
    $cabs :: ColIndex -> ColIndex
    abs :: ColIndex -> ColIndex
    $csignum :: ColIndex -> ColIndex
    signum :: ColIndex -> ColIndex
    $cfromInteger :: Integer -> ColIndex
    fromInteger :: Integer -> ColIndex
    Num, Int -> ColIndex -> ShowS
    [ColIndex] -> ShowS
    ColIndex -> String
    (Int -> ColIndex -> ShowS)
    -> (ColIndex -> String) -> ([ColIndex] -> ShowS) -> Show ColIndex
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ColIndex -> ShowS
    showsPrec :: Int -> ColIndex -> ShowS
    $cshow :: ColIndex -> String
    show :: ColIndex -> String
    $cshowList :: [ColIndex] -> ShowS
    showList :: [ColIndex] -> ShowS
    Show)

    -- | Index to a cell in a table part.
    type CellIndex = (RowIndex, ColIndex)

    -- | A grid cell contains either a real table cell, or is the
    -- continuation of a column or row-spanning cell. In the latter case,
    -- the index of the continued cell is provided.
    data GridCell a
      = ContentCell RowSpan ColSpan a
      | ContinuationCell CellIndex
      deriving stock (GridCell a -> GridCell a -> Bool
    (GridCell a -> GridCell a -> Bool)
    -> (GridCell a -> GridCell a -> Bool) -> Eq (GridCell a)
    forall a. Eq a => GridCell a -> GridCell a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => GridCell a -> GridCell a -> Bool
    == :: GridCell a -> GridCell a -> Bool
    $c/= :: forall a. Eq a => GridCell a -> GridCell a -> Bool
    /= :: GridCell a -> GridCell a -> Bool
    Eq, Int -> GridCell a -> ShowS
    [GridCell a] -> ShowS
    GridCell a -> String
    (Int -> GridCell a -> ShowS)
    -> (GridCell a -> String)
    -> ([GridCell a] -> ShowS)
    -> Show (GridCell a)
    forall a. Show a => Int -> GridCell a -> ShowS
    forall a. Show a => [GridCell a] -> ShowS
    forall a. Show a => GridCell a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> GridCell a -> ShowS
    showsPrec :: Int -> GridCell a -> ShowS
    $cshow :: forall a. Show a => GridCell a -> String
    show :: GridCell a -> String
    $cshowList :: forall a. Show a => [GridCell a] -> ShowS
    showList :: [GridCell a] -> ShowS
    Show)

    -- | The number of rows spanned by a cell.
    newtype RowSpan = RowSpan Int
      deriving stock (RowSpan -> RowSpan -> Bool
    (RowSpan -> RowSpan -> Bool)
    -> (RowSpan -> RowSpan -> Bool) -> Eq RowSpan
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: RowSpan -> RowSpan -> Bool
    == :: RowSpan -> RowSpan -> Bool
    $c/= :: RowSpan -> RowSpan -> Bool
    /= :: RowSpan -> RowSpan -> Bool
    Eq, Eq RowSpan
    Eq RowSpan =>
    (RowSpan -> RowSpan -> Ordering)
    -> (RowSpan -> RowSpan -> Bool)
    -> (RowSpan -> RowSpan -> Bool)
    -> (RowSpan -> RowSpan -> Bool)
    -> (RowSpan -> RowSpan -> Bool)
    -> (RowSpan -> RowSpan -> RowSpan)
    -> (RowSpan -> RowSpan -> RowSpan)
    -> Ord RowSpan
    RowSpan -> RowSpan -> Bool
    RowSpan -> RowSpan -> Ordering
    RowSpan -> RowSpan -> RowSpan
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: RowSpan -> RowSpan -> Ordering
    compare :: RowSpan -> RowSpan -> Ordering
    $c< :: RowSpan -> RowSpan -> Bool
    < :: RowSpan -> RowSpan -> Bool
    $c<= :: RowSpan -> RowSpan -> Bool
    <= :: RowSpan -> RowSpan -> Bool
    $c> :: RowSpan -> RowSpan -> Bool
    > :: RowSpan -> RowSpan -> Bool
    $c>= :: RowSpan -> RowSpan -> Bool
    >= :: RowSpan -> RowSpan -> Bool
    $cmax :: RowSpan -> RowSpan -> RowSpan
    max :: RowSpan -> RowSpan -> RowSpan
    $cmin :: RowSpan -> RowSpan -> RowSpan
    min :: RowSpan -> RowSpan -> RowSpan
    Ord)
      deriving newtype (Int -> RowSpan
    RowSpan -> Int
    RowSpan -> [RowSpan]
    RowSpan -> RowSpan
    RowSpan -> RowSpan -> [RowSpan]
    RowSpan -> RowSpan -> RowSpan -> [RowSpan]
    (RowSpan -> RowSpan)
    -> (RowSpan -> RowSpan)
    -> (Int -> RowSpan)
    -> (RowSpan -> Int)
    -> (RowSpan -> [RowSpan])
    -> (RowSpan -> RowSpan -> [RowSpan])
    -> (RowSpan -> RowSpan -> [RowSpan])
    -> (RowSpan -> RowSpan -> RowSpan -> [RowSpan])
    -> Enum RowSpan
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: RowSpan -> RowSpan
    succ :: RowSpan -> RowSpan
    $cpred :: RowSpan -> RowSpan
    pred :: RowSpan -> RowSpan
    $ctoEnum :: Int -> RowSpan
    toEnum :: Int -> RowSpan
    $cfromEnum :: RowSpan -> Int
    fromEnum :: RowSpan -> Int
    $cenumFrom :: RowSpan -> [RowSpan]
    enumFrom :: RowSpan -> [RowSpan]
    $cenumFromThen :: RowSpan -> RowSpan -> [RowSpan]
    enumFromThen :: RowSpan -> RowSpan -> [RowSpan]
    $cenumFromTo :: RowSpan -> RowSpan -> [RowSpan]
    enumFromTo :: RowSpan -> RowSpan -> [RowSpan]
    $cenumFromThenTo :: RowSpan -> RowSpan -> RowSpan -> [RowSpan]
    enumFromThenTo :: RowSpan -> RowSpan -> RowSpan -> [RowSpan]
    Enum, Integer -> RowSpan
    RowSpan -> RowSpan
    RowSpan -> RowSpan -> RowSpan
    (RowSpan -> RowSpan -> RowSpan)
    -> (RowSpan -> RowSpan -> RowSpan)
    -> (RowSpan -> RowSpan -> RowSpan)
    -> (RowSpan -> RowSpan)
    -> (RowSpan -> RowSpan)
    -> (RowSpan -> RowSpan)
    -> (Integer -> RowSpan)
    -> Num RowSpan
    forall a.
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (Integer -> a)
    -> Num a
    $c+ :: RowSpan -> RowSpan -> RowSpan
    + :: RowSpan -> RowSpan -> RowSpan
    $c- :: RowSpan -> RowSpan -> RowSpan
    - :: RowSpan -> RowSpan -> RowSpan
    $c* :: RowSpan -> RowSpan -> RowSpan
    * :: RowSpan -> RowSpan -> RowSpan
    $cnegate :: RowSpan -> RowSpan
    negate :: RowSpan -> RowSpan
    $cabs :: RowSpan -> RowSpan
    abs :: RowSpan -> RowSpan
    $csignum :: RowSpan -> RowSpan
    signum :: RowSpan -> RowSpan
    $cfromInteger :: Integer -> RowSpan
    fromInteger :: Integer -> RowSpan
    Num, ReadPrec [RowSpan]
    ReadPrec RowSpan
    Int -> ReadS RowSpan
    ReadS [RowSpan]
    (Int -> ReadS RowSpan)
    -> ReadS [RowSpan]
    -> ReadPrec RowSpan
    -> ReadPrec [RowSpan]
    -> Read RowSpan
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS RowSpan
    readsPrec :: Int -> ReadS RowSpan
    $creadList :: ReadS [RowSpan]
    readList :: ReadS [RowSpan]
    $creadPrec :: ReadPrec RowSpan
    readPrec :: ReadPrec RowSpan
    $creadListPrec :: ReadPrec [RowSpan]
    readListPrec :: ReadPrec [RowSpan]
    Read, Int -> RowSpan -> ShowS
    [RowSpan] -> ShowS
    RowSpan -> String
    (Int -> RowSpan -> ShowS)
    -> (RowSpan -> String) -> ([RowSpan] -> ShowS) -> Show RowSpan
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> RowSpan -> ShowS
    showsPrec :: Int -> RowSpan -> ShowS
    $cshow :: RowSpan -> String
    show :: RowSpan -> String
    $cshowList :: [RowSpan] -> ShowS
    showList :: [RowSpan] -> ShowS
    Show)

    -- | The number of columns spanned by a cell.
    newtype ColSpan = ColSpan Int
      deriving stock (ColSpan -> ColSpan -> Bool
    (ColSpan -> ColSpan -> Bool)
    -> (ColSpan -> ColSpan -> Bool) -> Eq ColSpan
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ColSpan -> ColSpan -> Bool
    == :: ColSpan -> ColSpan -> Bool
    $c/= :: ColSpan -> ColSpan -> Bool
    /= :: ColSpan -> ColSpan -> Bool
    Eq, Eq ColSpan
    Eq ColSpan =>
    (ColSpan -> ColSpan -> Ordering)
    -> (ColSpan -> ColSpan -> Bool)
    -> (ColSpan -> ColSpan -> Bool)
    -> (ColSpan -> ColSpan -> Bool)
    -> (ColSpan -> ColSpan -> Bool)
    -> (ColSpan -> ColSpan -> ColSpan)
    -> (ColSpan -> ColSpan -> ColSpan)
    -> Ord ColSpan
    ColSpan -> ColSpan -> Bool
    ColSpan -> ColSpan -> Ordering
    ColSpan -> ColSpan -> ColSpan
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ColSpan -> ColSpan -> Ordering
    compare :: ColSpan -> ColSpan -> Ordering
    $c< :: ColSpan -> ColSpan -> Bool
    < :: ColSpan -> ColSpan -> Bool
    $c<= :: ColSpan -> ColSpan -> Bool
    <= :: ColSpan -> ColSpan -> Bool
    $c> :: ColSpan -> ColSpan -> Bool
    > :: ColSpan -> ColSpan -> Bool
    $c>= :: ColSpan -> ColSpan -> Bool
    >= :: ColSpan -> ColSpan -> Bool
    $cmax :: ColSpan -> ColSpan -> ColSpan
    max :: ColSpan -> ColSpan -> ColSpan
    $cmin :: ColSpan -> ColSpan -> ColSpan
    min :: ColSpan -> ColSpan -> ColSpan
    Ord)
      deriving newtype (Int -> ColSpan
    ColSpan -> Int
    ColSpan -> [ColSpan]
    ColSpan -> ColSpan
    ColSpan -> ColSpan -> [ColSpan]
    ColSpan -> ColSpan -> ColSpan -> [ColSpan]
    (ColSpan -> ColSpan)
    -> (ColSpan -> ColSpan)
    -> (Int -> ColSpan)
    -> (ColSpan -> Int)
    -> (ColSpan -> [ColSpan])
    -> (ColSpan -> ColSpan -> [ColSpan])
    -> (ColSpan -> ColSpan -> [ColSpan])
    -> (ColSpan -> ColSpan -> ColSpan -> [ColSpan])
    -> Enum ColSpan
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: ColSpan -> ColSpan
    succ :: ColSpan -> ColSpan
    $cpred :: ColSpan -> ColSpan
    pred :: ColSpan -> ColSpan
    $ctoEnum :: Int -> ColSpan
    toEnum :: Int -> ColSpan
    $cfromEnum :: ColSpan -> Int
    fromEnum :: ColSpan -> Int
    $cenumFrom :: ColSpan -> [ColSpan]
    enumFrom :: ColSpan -> [ColSpan]
    $cenumFromThen :: ColSpan -> ColSpan -> [ColSpan]
    enumFromThen :: ColSpan -> ColSpan -> [ColSpan]
    $cenumFromTo :: ColSpan -> ColSpan -> [ColSpan]
    enumFromTo :: ColSpan -> ColSpan -> [ColSpan]
    $cenumFromThenTo :: ColSpan -> ColSpan -> ColSpan -> [ColSpan]
    enumFromThenTo :: ColSpan -> ColSpan -> ColSpan -> [ColSpan]
    Enum, Integer -> ColSpan
    ColSpan -> ColSpan
    ColSpan -> ColSpan -> ColSpan
    (ColSpan -> ColSpan -> ColSpan)
    -> (ColSpan -> ColSpan -> ColSpan)
    -> (ColSpan -> ColSpan -> ColSpan)
    -> (ColSpan -> ColSpan)
    -> (ColSpan -> ColSpan)
    -> (ColSpan -> ColSpan)
    -> (Integer -> ColSpan)
    -> Num ColSpan
    forall a.
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (Integer -> a)
    -> Num a
    $c+ :: ColSpan -> ColSpan -> ColSpan
    + :: ColSpan -> ColSpan -> ColSpan
    $c- :: ColSpan -> ColSpan -> ColSpan
    - :: ColSpan -> ColSpan -> ColSpan
    $c* :: ColSpan -> ColSpan -> ColSpan
    * :: ColSpan -> ColSpan -> ColSpan
    $cnegate :: ColSpan -> ColSpan
    negate :: ColSpan -> ColSpan
    $cabs :: ColSpan -> ColSpan
    abs :: ColSpan -> ColSpan
    $csignum :: ColSpan -> ColSpan
    signum :: ColSpan -> ColSpan
    $cfromInteger :: Integer -> ColSpan
    fromInteger :: Integer -> ColSpan
    Num, ReadPrec [ColSpan]
    ReadPrec ColSpan
    Int -> ReadS ColSpan
    ReadS [ColSpan]
    (Int -> ReadS ColSpan)
    -> ReadS [ColSpan]
    -> ReadPrec ColSpan
    -> ReadPrec [ColSpan]
    -> Read ColSpan
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS ColSpan
    readsPrec :: Int -> ReadS ColSpan
    $creadList :: ReadS [ColSpan]
    readList :: ReadS [ColSpan]
    $creadPrec :: ReadPrec ColSpan
    readPrec :: ReadPrec ColSpan
    $creadListPrec :: ReadPrec [ColSpan]
    readListPrec :: ReadPrec [ColSpan]
    Read, Int -> ColSpan -> ShowS
    [ColSpan] -> ShowS
    ColSpan -> String
    (Int -> ColSpan -> ShowS)
    -> (ColSpan -> String) -> ([ColSpan] -> ShowS) -> Show ColSpan
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ColSpan -> ShowS
    showsPrec :: Int -> ColSpan -> ShowS
    $cshow :: ColSpan -> String
    show :: ColSpan -> String
    $cshowList :: [ColSpan] -> ShowS
    showList :: [ColSpan] -> ShowS
    Show)

    -- | Cell alignment
    data Alignment
      = AlignDefault
      | AlignLeft
      | AlignCenter
      | AlignRight
      deriving stock (Int -> Alignment
    Alignment -> Int
    Alignment -> [Alignment]
    Alignment -> Alignment
    Alignment -> Alignment -> [Alignment]
    Alignment -> Alignment -> Alignment -> [Alignment]
    (Alignment -> Alignment)
    -> (Alignment -> Alignment)
    -> (Int -> Alignment)
    -> (Alignment -> Int)
    -> (Alignment -> [Alignment])
    -> (Alignment -> Alignment -> [Alignment])
    -> (Alignment -> Alignment -> [Alignment])
    -> (Alignment -> Alignment -> Alignment -> [Alignment])
    -> Enum Alignment
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: Alignment -> Alignment
    succ :: Alignment -> Alignment
    $cpred :: Alignment -> Alignment
    pred :: Alignment -> Alignment
    $ctoEnum :: Int -> Alignment
    toEnum :: Int -> Alignment
    $cfromEnum :: Alignment -> Int
    fromEnum :: Alignment -> Int
    $cenumFrom :: Alignment -> [Alignment]
    enumFrom :: Alignment -> [Alignment]
    $cenumFromThen :: Alignment -> Alignment -> [Alignment]
    enumFromThen :: Alignment -> Alignment -> [Alignment]
    $cenumFromTo :: Alignment -> Alignment -> [Alignment]
    enumFromTo :: Alignment -> Alignment -> [Alignment]
    $cenumFromThenTo :: Alignment -> Alignment -> Alignment -> [Alignment]
    enumFromThenTo :: Alignment -> Alignment -> Alignment -> [Alignment]
    Enum, Alignment -> Alignment -> Bool
    (Alignment -> Alignment -> Bool)
    -> (Alignment -> Alignment -> Bool) -> Eq Alignment
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Alignment -> Alignment -> Bool
    == :: Alignment -> Alignment -> Bool
    $c/= :: Alignment -> Alignment -> Bool
    /= :: Alignment -> Alignment -> Bool
    Eq, Eq Alignment
    Eq Alignment =>
    (Alignment -> Alignment -> Ordering)
    -> (Alignment -> Alignment -> Bool)
    -> (Alignment -> Alignment -> Bool)
    -> (Alignment -> Alignment -> Bool)
    -> (Alignment -> Alignment -> Bool)
    -> (Alignment -> Alignment -> Alignment)
    -> (Alignment -> Alignment -> Alignment)
    -> Ord Alignment
    Alignment -> Alignment -> Bool
    Alignment -> Alignment -> Ordering
    Alignment -> Alignment -> Alignment
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Alignment -> Alignment -> Ordering
    compare :: Alignment -> Alignment -> Ordering
    $c< :: Alignment -> Alignment -> Bool
    < :: Alignment -> Alignment -> Bool
    $c<= :: Alignment -> Alignment -> Bool
    <= :: Alignment -> Alignment -> Bool
    $c> :: Alignment -> Alignment -> Bool
    > :: Alignment -> Alignment -> Bool
    $c>= :: Alignment -> Alignment -> Bool
    >= :: Alignment -> Alignment -> Bool
    $cmax :: Alignment -> Alignment -> Alignment
    max :: Alignment -> Alignment -> Alignment
    $cmin :: Alignment -> Alignment -> Alignment
    min :: Alignment -> Alignment -> Alignment
    Ord, ReadPrec [Alignment]
    ReadPrec Alignment
    Int -> ReadS Alignment
    ReadS [Alignment]
    (Int -> ReadS Alignment)
    -> ReadS [Alignment]
    -> ReadPrec Alignment
    -> ReadPrec [Alignment]
    -> Read Alignment
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Alignment
    readsPrec :: Int -> ReadS Alignment
    $creadList :: ReadS [Alignment]
    readList :: ReadS [Alignment]
    $creadPrec :: ReadPrec Alignment
    readPrec :: ReadPrec Alignment
    $creadListPrec :: ReadPrec [Alignment]
    readListPrec :: ReadPrec [Alignment]
    Read, Int -> Alignment -> ShowS
    [Alignment] -> ShowS
    Alignment -> String
    (Int -> Alignment -> ShowS)
    -> (Alignment -> String)
    -> ([Alignment] -> ShowS)
    -> Show Alignment
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Alignment -> ShowS
    showsPrec :: Int -> Alignment -> ShowS
    $cshow :: Alignment -> String
    show :: Alignment -> String
    $cshowList :: [Alignment] -> ShowS
    showList :: [Alignment] -> ShowS
    Show)