{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE GADTs #-}
module Numeric.LAPACK.Matrix.Extent.Private where

import Numeric.LAPACK.Shape.Private (Unchecked(deconsUnchecked))
import Numeric.LAPACK.Wrapper (Flip(Flip, getFlip))

import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Shape ((::+)((::+)))

import Text.Printf (printf)

import Control.DeepSeq (NFData, rnf)
import Control.Applicative (Const(Const))

import Data.Maybe.HT (toMaybe)


data Extent meas vert horiz height width where
   Square :: size -> Extent Shape Small Small size size
   Separate :: height -> width -> Extent Size vert horiz height width


instance
   (Measure measure, C vertical, C horizontal, NFData height, NFData width) =>
      NFData (Extent measure vertical horizontal height width) where
   rnf :: Extent measure vertical horizontal height width -> ()
rnf (Square height
s) = height -> ()
forall a. NFData a => a -> ()
rnf height
s
   rnf (Separate height
h width
w) = (height, width) -> ()
forall a. NFData a => a -> ()
rnf (height
h,width
w)


data Big = Big deriving (Big -> Big -> Bool
(Big -> Big -> Bool) -> (Big -> Big -> Bool) -> Eq Big
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Big -> Big -> Bool
$c/= :: Big -> Big -> Bool
== :: Big -> Big -> Bool
$c== :: Big -> Big -> Bool
Eq,Int -> Big -> ShowS
[Big] -> ShowS
Big -> String
(Int -> Big -> ShowS)
-> (Big -> String) -> ([Big] -> ShowS) -> Show Big
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Big] -> ShowS
$cshowList :: [Big] -> ShowS
show :: Big -> String
$cshow :: Big -> String
showsPrec :: Int -> Big -> ShowS
$cshowsPrec :: Int -> Big -> ShowS
Show)
data Small = Small deriving (Small -> Small -> Bool
(Small -> Small -> Bool) -> (Small -> Small -> Bool) -> Eq Small
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Small -> Small -> Bool
$c/= :: Small -> Small -> Bool
== :: Small -> Small -> Bool
$c== :: Small -> Small -> Bool
Eq,Int -> Small -> ShowS
[Small] -> ShowS
Small -> String
(Int -> Small -> ShowS)
-> (Small -> String) -> ([Small] -> ShowS) -> Show Small
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Small] -> ShowS
$cshowList :: [Small] -> ShowS
show :: Small -> String
$cshow :: Small -> String
showsPrec :: Int -> Small -> ShowS
$cshowsPrec :: Int -> Small -> ShowS
Show)

instance NFData Big where rnf :: Big -> ()
rnf Big
Big = ()
instance NFData Small where rnf :: Small -> ()
rnf Small
Small = ()


data Size = Size deriving (Size -> Size -> Bool
(Size -> Size -> Bool) -> (Size -> Size -> Bool) -> Eq Size
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Size -> Size -> Bool
$c/= :: Size -> Size -> Bool
== :: Size -> Size -> Bool
$c== :: Size -> Size -> Bool
Eq,Int -> Size -> ShowS
[Size] -> ShowS
Size -> String
(Int -> Size -> ShowS)
-> (Size -> String) -> ([Size] -> ShowS) -> Show Size
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Size] -> ShowS
$cshowList :: [Size] -> ShowS
show :: Size -> String
$cshow :: Size -> String
showsPrec :: Int -> Size -> ShowS
$cshowsPrec :: Int -> Size -> ShowS
Show)
data Shape = Shape deriving (Shape -> Shape -> Bool
(Shape -> Shape -> Bool) -> (Shape -> Shape -> Bool) -> Eq Shape
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Shape -> Shape -> Bool
$c/= :: Shape -> Shape -> Bool
== :: Shape -> Shape -> Bool
$c== :: Shape -> Shape -> Bool
Eq,Int -> Shape -> ShowS
[Shape] -> ShowS
Shape -> String
(Int -> Shape -> ShowS)
-> (Shape -> String) -> ([Shape] -> ShowS) -> Show Shape
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Shape] -> ShowS
$cshowList :: [Shape] -> ShowS
show :: Shape -> String
$cshow :: Shape -> String
showsPrec :: Int -> Shape -> ShowS
$cshowsPrec :: Int -> Shape -> ShowS
Show)

instance NFData Size where rnf :: Size -> ()
rnf Size
Size = ()
instance NFData Shape where rnf :: Shape -> ()
rnf Shape
Shape = ()


type General = Extent Size Big Big
type Tall = Extent Size Big Small
type Wide = Extent Size Small Big
type SquareMeas meas = Extent meas Small Small
type LiberalSquare = SquareMeas Size
type Square sh = SquareMeas Shape sh sh


general :: height -> width -> General height width
general :: height -> width -> General height width
general = height -> width -> General height width
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate

tall :: height -> width -> Tall height width
tall :: height -> width -> Tall height width
tall = height -> width -> Tall height width
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate

wide :: height -> width -> Wide height width
wide :: height -> width -> Wide height width
wide = height -> width -> Wide height width
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate

liberalSquare :: height -> width -> LiberalSquare height width
liberalSquare :: height -> width -> LiberalSquare height width
liberalSquare = height -> width -> LiberalSquare height width
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate

square :: sh -> Square sh
square :: sh -> Square sh
square = sh -> Square sh
forall size. size -> Extent Shape Small Small size size
Square


type Map measA vertA horizA measB vertB horizB height width =
         Extent measA vertA horizA height width ->
         Extent measB vertB horizB height width


class C tag where switchTag :: f Small -> f Big -> f tag
instance C Small where switchTag :: f Small -> f Big -> f Small
switchTag f Small
f f Big
_ = f Small
f
instance C Big where switchTag :: f Small -> f Big -> f Big
switchTag f Small
_ f Big
f = f Big
f

class Measure meas where switchMeasure :: f Shape -> f Size -> f meas
instance Measure Shape where switchMeasure :: f Shape -> f Size -> f Shape
switchMeasure f Shape
f f Size
_ = f Shape
f
instance Measure Size where switchMeasure :: f Shape -> f Size -> f Size
switchMeasure f Shape
_ f Size
f = f Size
f


switchTagPair ::
   (C vert, C horiz) =>
   f Small Small -> f Small Big -> f Big Small -> f Big Big -> f vert horiz
switchTagPair :: f Small Small
-> f Small Big -> f Big Small -> f Big Big -> f vert horiz
switchTagPair f Small Small
fSquare f Small Big
fWide f Big Small
fTall f Big Big
fGeneral =
   Flip f horiz vert -> f vert horiz
forall (f :: * -> * -> *) b a. Flip f b a -> f a b
getFlip (Flip f horiz vert -> f vert horiz)
-> Flip f horiz vert -> f vert horiz
forall a b. (a -> b) -> a -> b
$
   Flip f horiz Small -> Flip f horiz Big -> Flip f horiz vert
forall tag (f :: * -> *). C tag => f Small -> f Big -> f tag
switchTag
      (f Small horiz -> Flip f horiz Small
forall (f :: * -> * -> *) b a. f a b -> Flip f b a
Flip (f Small horiz -> Flip f horiz Small)
-> f Small horiz -> Flip f horiz Small
forall a b. (a -> b) -> a -> b
$ f Small Small -> f Small Big -> f Small horiz
forall tag (f :: * -> *). C tag => f Small -> f Big -> f tag
switchTag f Small Small
fSquare f Small Big
fWide)
      (f Big horiz -> Flip f horiz Big
forall (f :: * -> * -> *) b a. f a b -> Flip f b a
Flip (f Big horiz -> Flip f horiz Big)
-> f Big horiz -> Flip f horiz Big
forall a b. (a -> b) -> a -> b
$ f Big Small -> f Big Big -> f Big horiz
forall tag (f :: * -> *). C tag => f Small -> f Big -> f tag
switchTag f Big Small
fTall f Big Big
fGeneral)


newtype RotLeft3 f b c a = RotLeft3 {RotLeft3 f b c a -> f a b c
getRotLeft3 :: f a b c}

switchMeasureExtent ::
   (Measure meas, C vert, C horiz) =>
   f Shape Small Small ->
   (forall vert0 horiz0. (C vert0, C horiz0) => f Size vert0 horiz0) ->
   f meas vert horiz
switchMeasureExtent :: f Shape Small Small
-> (forall vert0 horiz0.
    (C vert0, C horiz0) =>
    f Size vert0 horiz0)
-> f meas vert horiz
switchMeasureExtent f Shape Small Small
fSquare forall vert0 horiz0. (C vert0, C horiz0) => f Size vert0 horiz0
fGeneral =
   RotLeft3 f vert horiz meas -> f meas vert horiz
forall (f :: * -> * -> * -> *) b c a. RotLeft3 f b c a -> f a b c
getRotLeft3 (RotLeft3 f vert horiz meas -> f meas vert horiz)
-> RotLeft3 f vert horiz meas -> f meas vert horiz
forall a b. (a -> b) -> a -> b
$
      RotLeft3 f vert horiz Shape
-> RotLeft3 f vert horiz Size -> RotLeft3 f vert horiz meas
forall meas (f :: * -> *).
Measure meas =>
f Shape -> f Size -> f meas
switchMeasure
         (f Shape vert horiz -> RotLeft3 f vert horiz Shape
forall (f :: * -> * -> * -> *) b c a. f a b c -> RotLeft3 f b c a
RotLeft3 (f Shape vert horiz -> RotLeft3 f vert horiz Shape)
-> f Shape vert horiz -> RotLeft3 f vert horiz Shape
forall a b. (a -> b) -> a -> b
$ f Shape Small Small
-> f Shape Small Big
-> f Shape Big Small
-> f Shape Big Big
-> f Shape vert horiz
forall vert horiz (f :: * -> * -> *).
(C vert, C horiz) =>
f Small Small
-> f Small Big -> f Big Small -> f Big Big -> f vert horiz
switchTagPair f Shape Small Small
fSquare
                        f Shape Small Big
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f meas vert horiz
errorTagTriple f Shape Big Small
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f meas vert horiz
errorTagTriple f Shape Big Big
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f meas vert horiz
errorTagTriple)
         (f Size vert horiz -> RotLeft3 f vert horiz Size
forall (f :: * -> * -> * -> *) b c a. f a b c -> RotLeft3 f b c a
RotLeft3 (f Size vert horiz -> RotLeft3 f vert horiz Size)
-> f Size vert horiz -> RotLeft3 f vert horiz Size
forall a b. (a -> b) -> a -> b
$ f Size Small Small
-> f Size Small Big
-> f Size Big Small
-> f Size Big Big
-> f Size vert horiz
forall vert horiz (f :: * -> * -> *).
(C vert, C horiz) =>
f Small Small
-> f Small Big -> f Big Small -> f Big Big -> f vert horiz
switchTagPair f Size Small Small
forall vert0 horiz0. (C vert0, C horiz0) => f Size vert0 horiz0
fGeneral f Size Small Big
forall vert0 horiz0. (C vert0, C horiz0) => f Size vert0 horiz0
fGeneral f Size Big Small
forall vert0 horiz0. (C vert0, C horiz0) => f Size vert0 horiz0
fGeneral f Size Big Big
forall vert0 horiz0. (C vert0, C horiz0) => f Size vert0 horiz0
fGeneral)


errorTagTripleAux ::
   Const String meas -> Const String vert -> Const String horiz ->
   f meas vert horiz
errorTagTripleAux :: Const String meas
-> Const String vert -> Const String horiz -> f meas vert horiz
errorTagTripleAux (Const String
meas) (Const String
vert) (Const String
horiz) =
   String -> f meas vert horiz
forall a. HasCallStack => String -> a
error (String -> f meas vert horiz) -> String -> f meas vert horiz
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> ShowS
forall r. PrintfType r => String -> r
printf String
"forbidden Extent tag combination %s %s %s" String
meas String
vert String
horiz

showConst :: (Show a) => a -> Const String a
showConst :: a -> Const String a
showConst a
a = String -> Const String a
forall k a (b :: k). a -> Const a b
Const (String -> Const String a) -> String -> Const String a
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Show a => a -> String
show a
a

errorTagTriple :: (Measure meas, C vert, C horiz) => f meas vert horiz
errorTagTriple :: f meas vert horiz
errorTagTriple =
   Const String meas
-> Const String vert -> Const String horiz -> f meas vert horiz
forall meas vert horiz (f :: * -> * -> * -> *).
Const String meas
-> Const String vert -> Const String horiz -> f meas vert horiz
errorTagTripleAux
      (Const String Shape -> Const String Size -> Const String meas
forall meas (f :: * -> *).
Measure meas =>
f Shape -> f Size -> f meas
switchMeasure (Shape -> Const String Shape
forall a. Show a => a -> Const String a
showConst Shape
Shape) (Size -> Const String Size
forall a. Show a => a -> Const String a
showConst Size
Size))
      (Const String Small -> Const String Big -> Const String vert
forall tag (f :: * -> *). C tag => f Small -> f Big -> f tag
switchTag (Small -> Const String Small
forall a. Show a => a -> Const String a
showConst Small
Small) (Big -> Const String Big
forall a. Show a => a -> Const String a
showConst Big
Big))
      (Const String Small -> Const String Big -> Const String horiz
forall tag (f :: * -> *). C tag => f Small -> f Big -> f tag
switchTag (Small -> Const String Small
forall a. Show a => a -> Const String a
showConst Small
Small) (Big -> Const String Big
forall a. Show a => a -> Const String a
showConst Big
Big))

switchTagTriple ::
   (Measure meas, C vert, C horiz) =>
   f Shape Small Small -> f Size Small Small -> f Size Small Big ->
   f Size Big Small -> f Size Big Big -> f meas vert horiz
switchTagTriple :: f Shape Small Small
-> f Size Small Small
-> f Size Small Big
-> f Size Big Small
-> f Size Big Big
-> f meas vert horiz
switchTagTriple f Shape Small Small
fSquare f Size Small Small
fLiberalSquare f Size Small Big
fWide f Size Big Small
fTall f Size Big Big
fGeneral =
   RotLeft3 f vert horiz meas -> f meas vert horiz
forall (f :: * -> * -> * -> *) b c a. RotLeft3 f b c a -> f a b c
getRotLeft3 (RotLeft3 f vert horiz meas -> f meas vert horiz)
-> RotLeft3 f vert horiz meas -> f meas vert horiz
forall a b. (a -> b) -> a -> b
$
      RotLeft3 f vert horiz Shape
-> RotLeft3 f vert horiz Size -> RotLeft3 f vert horiz meas
forall meas (f :: * -> *).
Measure meas =>
f Shape -> f Size -> f meas
switchMeasure
         (f Shape vert horiz -> RotLeft3 f vert horiz Shape
forall (f :: * -> * -> * -> *) b c a. f a b c -> RotLeft3 f b c a
RotLeft3 (f Shape vert horiz -> RotLeft3 f vert horiz Shape)
-> f Shape vert horiz -> RotLeft3 f vert horiz Shape
forall a b. (a -> b) -> a -> b
$ f Shape Small Small
-> f Shape Small Big
-> f Shape Big Small
-> f Shape Big Big
-> f Shape vert horiz
forall vert horiz (f :: * -> * -> *).
(C vert, C horiz) =>
f Small Small
-> f Small Big -> f Big Small -> f Big Big -> f vert horiz
switchTagPair f Shape Small Small
fSquare
                        f Shape Small Big
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f meas vert horiz
errorTagTriple f Shape Big Small
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f meas vert horiz
errorTagTriple f Shape Big Big
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f meas vert horiz
errorTagTriple)
         (f Size vert horiz -> RotLeft3 f vert horiz Size
forall (f :: * -> * -> * -> *) b c a. f a b c -> RotLeft3 f b c a
RotLeft3 (f Size vert horiz -> RotLeft3 f vert horiz Size)
-> f Size vert horiz -> RotLeft3 f vert horiz Size
forall a b. (a -> b) -> a -> b
$ f Size Small Small
-> f Size Small Big
-> f Size Big Small
-> f Size Big Big
-> f Size vert horiz
forall vert horiz (f :: * -> * -> *).
(C vert, C horiz) =>
f Small Small
-> f Small Big -> f Big Small -> f Big Big -> f vert horiz
switchTagPair f Size Small Small
fLiberalSquare f Size Small Big
fWide f Size Big Small
fTall f Size Big Big
fGeneral)


caseTallWide ::
   (Measure meas, C vert, C horiz) =>
   (height -> width -> Bool) ->
   Extent meas vert horiz height width ->
   Either (Tall height width) (Wide height width)
caseTallWide :: (height -> width -> Bool)
-> Extent meas vert horiz height width
-> Either (Tall height width) (Wide height width)
caseTallWide height -> width -> Bool
_ (Square height
sh) = Tall height height
-> Either (Tall height height) (Wide height width)
forall a b. a -> Either a b
Left (Tall height height
 -> Either (Tall height height) (Wide height width))
-> Tall height height
-> Either (Tall height height) (Wide height width)
forall a b. (a -> b) -> a -> b
$ height -> height -> Tall height height
forall height width. height -> width -> Tall height width
tall height
sh height
sh
caseTallWide height -> width -> Bool
ge x :: Extent meas vert horiz height width
x@(Separate height
_ width
_) =
   (Accessor
   (Either
      (Extent meas Big Small height width)
      (Extent meas Small Big height width))
   height
   width
   meas
   vert
   horiz
 -> Extent meas vert horiz height width
 -> Either
      (Extent meas Big Small height width)
      (Extent meas Small Big height width))
-> Extent meas vert horiz height width
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     vert
     horiz
-> Either
     (Extent meas Big Small height width)
     (Extent meas Small Big height width)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Accessor
  (Either
     (Extent meas Big Small height width)
     (Extent meas Small Big height width))
  height
  width
  meas
  vert
  horiz
-> Extent meas vert horiz height width
-> Either
     (Extent meas Big Small height width)
     (Extent meas Small Big height width)
forall a height width meas vert horiz.
Accessor a height width meas vert horiz
-> Extent meas vert horiz height width -> a
getAccessor Extent meas vert horiz height width
x (Accessor
   (Either
      (Extent meas Big Small height width)
      (Extent meas Small Big height width))
   height
   width
   meas
   vert
   horiz
 -> Either
      (Extent meas Big Small height width)
      (Extent meas Small Big height width))
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     vert
     horiz
-> Either
     (Extent meas Big Small height width)
     (Extent meas Small Big height width)
forall a b. (a -> b) -> a -> b
$
   Accessor
  (Either
     (Extent meas Big Small height width)
     (Extent meas Small Big height width))
  height
  width
  meas
  Small
  Small
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     Small
     Big
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     Big
     Small
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     Big
     Big
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     vert
     horiz
forall vert horiz (f :: * -> * -> *).
(C vert, C horiz) =>
f Small Small
-> f Small Big -> f Big Small -> f Big Big -> f vert horiz
switchTagPair
      ((Extent meas Small Small height width
 -> Either
      (Extent meas Big Small height width)
      (Extent meas Small Big height width))
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     Small
     Small
forall a height width meas vert horiz.
(Extent meas vert horiz height width -> a)
-> Accessor a height width meas vert horiz
Accessor ((Extent meas Small Small height width
  -> Either
       (Extent meas Big Small height width)
       (Extent meas Small Big height width))
 -> Accessor
      (Either
         (Extent meas Big Small height width)
         (Extent meas Small Big height width))
      height
      width
      meas
      Small
      Small)
-> (Extent meas Small Small height width
    -> Either
         (Extent meas Big Small height width)
         (Extent meas Small Big height width))
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     Small
     Small
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> Tall height width -> Either (Tall height width) (Wide height width)
forall a b. a -> Either a b
Left (Tall height width
 -> Either (Tall height width) (Wide height width))
-> Tall height width
-> Either (Tall height width) (Wide height width)
forall a b. (a -> b) -> a -> b
$ height -> width -> Tall height width
forall height width. height -> width -> Tall height width
tall height
h width
w)
      ((Extent meas Small Big height width
 -> Either
      (Extent meas Big Small height width)
      (Extent meas Small Big height width))
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     Small
     Big
forall a height width meas vert horiz.
(Extent meas vert horiz height width -> a)
-> Accessor a height width meas vert horiz
Accessor Extent meas Small Big height width
-> Either
     (Extent meas Big Small height width)
     (Extent meas Small Big height width)
forall a b. b -> Either a b
Right)
      ((Extent meas Big Small height width
 -> Either
      (Extent meas Big Small height width)
      (Extent meas Small Big height width))
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     Big
     Small
forall a height width meas vert horiz.
(Extent meas vert horiz height width -> a)
-> Accessor a height width meas vert horiz
Accessor Extent meas Big Small height width
-> Either
     (Extent meas Big Small height width)
     (Extent meas Small Big height width)
forall a b. a -> Either a b
Left)
      ((Extent meas Big Big height width
 -> Either
      (Extent meas Big Small height width)
      (Extent meas Small Big height width))
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     Big
     Big
forall a height width meas vert horiz.
(Extent meas vert horiz height width -> a)
-> Accessor a height width meas vert horiz
Accessor ((Extent meas Big Big height width
  -> Either
       (Extent meas Big Small height width)
       (Extent meas Small Big height width))
 -> Accessor
      (Either
         (Extent meas Big Small height width)
         (Extent meas Small Big height width))
      height
      width
      meas
      Big
      Big)
-> (Extent meas Big Big height width
    -> Either
         (Extent meas Big Small height width)
         (Extent meas Small Big height width))
-> Accessor
     (Either
        (Extent meas Big Small height width)
        (Extent meas Small Big height width))
     height
     width
     meas
     Big
     Big
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) ->
         if height -> width -> Bool
ge height
h width
w
            then Tall height width -> Either (Tall height width) (Wide height width)
forall a b. a -> Either a b
Left (Tall height width
 -> Either (Tall height width) (Wide height width))
-> Tall height width
-> Either (Tall height width) (Wide height width)
forall a b. (a -> b) -> a -> b
$ height -> width -> Tall height width
forall height width. height -> width -> Tall height width
tall height
h width
w
            else Wide height width -> Either (Tall height width) (Wide height width)
forall a b. b -> Either a b
Right (Wide height width
 -> Either (Tall height width) (Wide height width))
-> Wide height width
-> Either (Tall height width) (Wide height width)
forall a b. (a -> b) -> a -> b
$ height -> width -> Wide height width
forall height width. height -> width -> Wide height width
wide height
h width
w)


newtype GenSquare sh meas vert horiz =
   GenSquare {GenSquare sh meas vert horiz -> sh -> Extent meas vert horiz sh sh
getGenSquare :: sh -> Extent meas vert horiz sh sh}

genSquare ::
   (Measure meas, C vert, C horiz) => sh -> Extent meas vert horiz sh sh
genSquare :: sh -> Extent meas vert horiz sh sh
genSquare =
   GenSquare sh meas vert horiz -> sh -> Extent meas vert horiz sh sh
forall sh meas vert horiz.
GenSquare sh meas vert horiz -> sh -> Extent meas vert horiz sh sh
getGenSquare (GenSquare sh meas vert horiz
 -> sh -> Extent meas vert horiz sh sh)
-> GenSquare sh meas vert horiz
-> sh
-> Extent meas vert horiz sh sh
forall a b. (a -> b) -> a -> b
$
   GenSquare sh Shape Small Small
-> (forall vert0 horiz0.
    (C vert0, C horiz0) =>
    GenSquare sh Size vert0 horiz0)
-> GenSquare sh meas vert horiz
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f Shape Small Small
-> (forall vert0 horiz0.
    (C vert0, C horiz0) =>
    f Size vert0 horiz0)
-> f meas vert horiz
switchMeasureExtent
      ((sh -> Extent Shape Small Small sh sh)
-> GenSquare sh Shape Small Small
forall sh meas vert horiz.
(sh -> Extent meas vert horiz sh sh)
-> GenSquare sh meas vert horiz
GenSquare sh -> Extent Shape Small Small sh sh
forall size. size -> Extent Shape Small Small size size
square)
      ((sh -> Extent Size vert0 horiz0 sh sh)
-> GenSquare sh Size vert0 horiz0
forall sh meas vert horiz.
(sh -> Extent meas vert horiz sh sh)
-> GenSquare sh meas vert horiz
GenSquare (\sh
sh -> sh -> sh -> Extent Size vert0 horiz0 sh sh
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate sh
sh sh
sh))

genLiberalSquare ::
   (C vert, C horiz) => height -> width -> Extent Size vert horiz height width
genLiberalSquare :: height -> width -> Extent Size vert horiz height width
genLiberalSquare = height -> width -> Extent Size vert horiz height width
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate

relaxMeasure :: (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz height width ->
   Extent Size vert horiz height width
relaxMeasure :: Extent meas vert horiz height width
-> Extent Size vert horiz height width
relaxMeasure (Square height
s) = height -> Extent Size vert horiz height height
forall meas vert horiz sh.
(Measure meas, C vert, C horiz) =>
sh -> Extent meas vert horiz sh sh
genSquare height
s
relaxMeasure (Separate height
h width
w) = height -> width -> Extent Size vert horiz height width
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate height
h width
w

newtype GenTall height width meas vert horiz =
   GenTall {
      GenTall height width meas vert horiz
-> Extent meas vert Small height width
-> Extent Size vert horiz height width
getGenTall ::
         Extent meas vert Small height width ->
         Extent Size vert horiz height width
   }

generalizeTall :: (Measure meas, C vert, C horiz) =>
   Extent meas vert Small height width -> Extent Size vert horiz height width
generalizeTall :: Extent meas vert Small height width
-> Extent Size vert horiz height width
generalizeTall =
   GenTall height width Size vert horiz
-> Extent Size vert Small height width
-> Extent Size vert horiz height width
forall height width meas vert horiz.
GenTall height width meas vert horiz
-> Extent meas vert Small height width
-> Extent Size vert horiz height width
getGenTall
      (GenTall height width Size Small Small
-> GenTall height width Size Small Big
-> GenTall height width Size Big Small
-> GenTall height width Size Big Big
-> GenTall height width Size vert horiz
forall vert horiz (f :: * -> * -> *).
(C vert, C horiz) =>
f Small Small
-> f Small Big -> f Big Small -> f Big Big -> f vert horiz
switchTagPair
         ((Extent Size Small Small height width
 -> Extent Size Small Small height width)
-> GenTall height width Size Small Small
forall height width meas vert horiz.
(Extent meas vert Small height width
 -> Extent Size vert horiz height width)
-> GenTall height width meas vert horiz
GenTall Extent Size Small Small height width
-> Extent Size Small Small height width
forall a. a -> a
id) ((Extent Size Small Small height width
 -> Extent Size Small Big height width)
-> GenTall height width Size Small Big
forall height width meas vert horiz.
(Extent meas vert Small height width
 -> Extent Size vert horiz height width)
-> GenTall height width meas vert horiz
GenTall ((Extent Size Small Small height width
  -> Extent Size Small Big height width)
 -> GenTall height width Size Small Big)
-> (Extent Size Small Small height width
    -> Extent Size Small Big height width)
-> GenTall height width Size Small Big
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Small Big height width
forall height width. height -> width -> Wide height width
wide height
h width
w)
         ((Extent Size Big Small height width
 -> Extent Size Big Small height width)
-> GenTall height width Size Big Small
forall height width meas vert horiz.
(Extent meas vert Small height width
 -> Extent Size vert horiz height width)
-> GenTall height width meas vert horiz
GenTall Extent Size Big Small height width
-> Extent Size Big Small height width
forall a. a -> a
id) ((Extent Size Big Small height width
 -> Extent Size Big Big height width)
-> GenTall height width Size Big Big
forall height width meas vert horiz.
(Extent meas vert Small height width
 -> Extent Size vert horiz height width)
-> GenTall height width meas vert horiz
GenTall ((Extent Size Big Small height width
  -> Extent Size Big Big height width)
 -> GenTall height width Size Big Big)
-> (Extent Size Big Small height width
    -> Extent Size Big Big height width)
-> GenTall height width Size Big Big
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Big Big height width
forall height width. height -> width -> General height width
general height
h width
w))
   (Extent Size vert Small height width
 -> Extent Size vert horiz height width)
-> (Extent meas vert Small height width
    -> Extent Size vert Small height width)
-> Extent meas vert Small height width
-> Extent Size vert horiz height width
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   Extent meas vert Small height width
-> Extent Size vert Small height width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width
-> Extent Size vert horiz height width
relaxMeasure

newtype GenWide height width meas vert horiz =
   GenWide {
      GenWide height width meas vert horiz
-> Extent meas Small horiz height width
-> Extent Size vert horiz height width
getGenWide ::
         Extent meas Small horiz height width ->
         Extent Size vert horiz height width
   }

generalizeWide :: (Measure meas, C vert, C horiz) =>
   Extent meas Small horiz height width -> Extent Size vert horiz height width
generalizeWide :: Extent meas Small horiz height width
-> Extent Size vert horiz height width
generalizeWide =
   GenWide height width Size vert horiz
-> Extent Size Small horiz height width
-> Extent Size vert horiz height width
forall height width meas vert horiz.
GenWide height width meas vert horiz
-> Extent meas Small horiz height width
-> Extent Size vert horiz height width
getGenWide
      (GenWide height width Size Small Small
-> GenWide height width Size Small Big
-> GenWide height width Size Big Small
-> GenWide height width Size Big Big
-> GenWide height width Size vert horiz
forall vert horiz (f :: * -> * -> *).
(C vert, C horiz) =>
f Small Small
-> f Small Big -> f Big Small -> f Big Big -> f vert horiz
switchTagPair
         ((Extent Size Small Small height width
 -> Extent Size Small Small height width)
-> GenWide height width Size Small Small
forall height width meas vert horiz.
(Extent meas Small horiz height width
 -> Extent Size vert horiz height width)
-> GenWide height width meas vert horiz
GenWide Extent Size Small Small height width
-> Extent Size Small Small height width
forall a. a -> a
id)
         ((Extent Size Small Big height width
 -> Extent Size Small Big height width)
-> GenWide height width Size Small Big
forall height width meas vert horiz.
(Extent meas Small horiz height width
 -> Extent Size vert horiz height width)
-> GenWide height width meas vert horiz
GenWide Extent Size Small Big height width
-> Extent Size Small Big height width
forall a. a -> a
id)
         ((Extent Size Small Small height width
 -> Extent Size Big Small height width)
-> GenWide height width Size Big Small
forall height width meas vert horiz.
(Extent meas Small horiz height width
 -> Extent Size vert horiz height width)
-> GenWide height width meas vert horiz
GenWide ((Extent Size Small Small height width
  -> Extent Size Big Small height width)
 -> GenWide height width Size Big Small)
-> (Extent Size Small Small height width
    -> Extent Size Big Small height width)
-> GenWide height width Size Big Small
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Big Small height width
forall height width. height -> width -> Tall height width
tall height
h width
w)
         ((Extent Size Small Big height width
 -> Extent Size Big Big height width)
-> GenWide height width Size Big Big
forall height width meas vert horiz.
(Extent meas Small horiz height width
 -> Extent Size vert horiz height width)
-> GenWide height width meas vert horiz
GenWide ((Extent Size Small Big height width
  -> Extent Size Big Big height width)
 -> GenWide height width Size Big Big)
-> (Extent Size Small Big height width
    -> Extent Size Big Big height width)
-> GenWide height width Size Big Big
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Big Big height width
forall height width. height -> width -> General height width
general height
h width
w))
   (Extent Size Small horiz height width
 -> Extent Size vert horiz height width)
-> (Extent meas Small horiz height width
    -> Extent Size Small horiz height width)
-> Extent meas Small horiz height width
-> Extent Size vert horiz height width
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   Extent meas Small horiz height width
-> Extent Size Small horiz height width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width
-> Extent Size vert horiz height width
relaxMeasure


newtype WeakenTall height width meas vert horiz =
   WeakenTall {
      WeakenTall height width meas vert horiz
-> Extent meas vert Small height width
-> Extent meas vert horiz height width
getWeakenTall ::
         Extent meas vert Small height width ->
         Extent meas vert horiz height width
   }

weakenTall :: (Measure meas, C vert, C horiz) =>
   Extent meas vert Small height width -> Extent meas vert horiz height width
weakenTall :: Extent meas vert Small height width
-> Extent meas vert horiz height width
weakenTall =
   WeakenTall height width meas vert horiz
-> Extent meas vert Small height width
-> Extent meas vert horiz height width
forall height width meas vert horiz.
WeakenTall height width meas vert horiz
-> Extent meas vert Small height width
-> Extent meas vert horiz height width
getWeakenTall (WeakenTall height width meas vert horiz
 -> Extent meas vert Small height width
 -> Extent meas vert horiz height width)
-> WeakenTall height width meas vert horiz
-> Extent meas vert Small height width
-> Extent meas vert horiz height width
forall a b. (a -> b) -> a -> b
$
   WeakenTall height width Shape Small Small
-> WeakenTall height width Size Small Small
-> WeakenTall height width Size Small Big
-> WeakenTall height width Size Big Small
-> WeakenTall height width Size Big Big
-> WeakenTall height width meas vert horiz
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f Shape Small Small
-> f Size Small Small
-> f Size Small Big
-> f Size Big Small
-> f Size Big Big
-> f meas vert horiz
switchTagTriple
      ((Extent Shape Small Small height width
 -> Extent Shape Small Small height width)
-> WeakenTall height width Shape Small Small
forall height width meas vert horiz.
(Extent meas vert Small height width
 -> Extent meas vert horiz height width)
-> WeakenTall height width meas vert horiz
WeakenTall Extent Shape Small Small height width
-> Extent Shape Small Small height width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent Shape Small Small height width
-> Extent meas vert horiz height width
fromSquareLiberal)
      ((Extent Size Small Small height width
 -> Extent Size Small Small height width)
-> WeakenTall height width Size Small Small
forall height width meas vert horiz.
(Extent meas vert Small height width
 -> Extent meas vert horiz height width)
-> WeakenTall height width meas vert horiz
WeakenTall Extent Size Small Small height width
-> Extent Size Small Small height width
forall a. a -> a
id) ((Extent Size Small Small height width
 -> Extent Size Small Big height width)
-> WeakenTall height width Size Small Big
forall height width meas vert horiz.
(Extent meas vert Small height width
 -> Extent meas vert horiz height width)
-> WeakenTall height width meas vert horiz
WeakenTall ((Extent Size Small Small height width
  -> Extent Size Small Big height width)
 -> WeakenTall height width Size Small Big)
-> (Extent Size Small Small height width
    -> Extent Size Small Big height width)
-> WeakenTall height width Size Small Big
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Small Big height width
forall height width. height -> width -> Wide height width
wide height
h width
w)
      ((Extent Size Big Small height width
 -> Extent Size Big Small height width)
-> WeakenTall height width Size Big Small
forall height width meas vert horiz.
(Extent meas vert Small height width
 -> Extent meas vert horiz height width)
-> WeakenTall height width meas vert horiz
WeakenTall Extent Size Big Small height width
-> Extent Size Big Small height width
forall a. a -> a
id) ((Extent Size Big Small height width
 -> Extent Size Big Big height width)
-> WeakenTall height width Size Big Big
forall height width meas vert horiz.
(Extent meas vert Small height width
 -> Extent meas vert horiz height width)
-> WeakenTall height width meas vert horiz
WeakenTall ((Extent Size Big Small height width
  -> Extent Size Big Big height width)
 -> WeakenTall height width Size Big Big)
-> (Extent Size Big Small height width
    -> Extent Size Big Big height width)
-> WeakenTall height width Size Big Big
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Big Big height width
forall height width. height -> width -> General height width
general height
h width
w)

newtype WeakenWide height width meas vert horiz =
   WeakenWide {
      WeakenWide height width meas vert horiz
-> Extent meas Small horiz height width
-> Extent meas vert horiz height width
getWeakenWide ::
         Extent meas Small horiz height width ->
         Extent meas vert horiz height width
   }

weakenWide :: (Measure meas, C vert, C horiz) =>
   Extent meas Small horiz height width -> Extent meas vert horiz height width
weakenWide :: Extent meas Small horiz height width
-> Extent meas vert horiz height width
weakenWide =
   WeakenWide height width meas vert horiz
-> Extent meas Small horiz height width
-> Extent meas vert horiz height width
forall height width meas vert horiz.
WeakenWide height width meas vert horiz
-> Extent meas Small horiz height width
-> Extent meas vert horiz height width
getWeakenWide (WeakenWide height width meas vert horiz
 -> Extent meas Small horiz height width
 -> Extent meas vert horiz height width)
-> WeakenWide height width meas vert horiz
-> Extent meas Small horiz height width
-> Extent meas vert horiz height width
forall a b. (a -> b) -> a -> b
$
   WeakenWide height width Shape Small Small
-> WeakenWide height width Size Small Small
-> WeakenWide height width Size Small Big
-> WeakenWide height width Size Big Small
-> WeakenWide height width Size Big Big
-> WeakenWide height width meas vert horiz
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f Shape Small Small
-> f Size Small Small
-> f Size Small Big
-> f Size Big Small
-> f Size Big Big
-> f meas vert horiz
switchTagTriple
      ((Extent Shape Small Small height width
 -> Extent Shape Small Small height width)
-> WeakenWide height width Shape Small Small
forall height width meas vert horiz.
(Extent meas Small horiz height width
 -> Extent meas vert horiz height width)
-> WeakenWide height width meas vert horiz
WeakenWide Extent Shape Small Small height width
-> Extent Shape Small Small height width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent Shape Small Small height width
-> Extent meas vert horiz height width
fromSquareLiberal)
      ((Extent Size Small Small height width
 -> Extent Size Small Small height width)
-> WeakenWide height width Size Small Small
forall height width meas vert horiz.
(Extent meas Small horiz height width
 -> Extent meas vert horiz height width)
-> WeakenWide height width meas vert horiz
WeakenWide Extent Size Small Small height width
-> Extent Size Small Small height width
forall a. a -> a
id)
      ((Extent Size Small Big height width
 -> Extent Size Small Big height width)
-> WeakenWide height width Size Small Big
forall height width meas vert horiz.
(Extent meas Small horiz height width
 -> Extent meas vert horiz height width)
-> WeakenWide height width meas vert horiz
WeakenWide Extent Size Small Big height width
-> Extent Size Small Big height width
forall a. a -> a
id)
      ((Extent Size Small Small height width
 -> Extent Size Big Small height width)
-> WeakenWide height width Size Big Small
forall height width meas vert horiz.
(Extent meas Small horiz height width
 -> Extent meas vert horiz height width)
-> WeakenWide height width meas vert horiz
WeakenWide ((Extent Size Small Small height width
  -> Extent Size Big Small height width)
 -> WeakenWide height width Size Big Small)
-> (Extent Size Small Small height width
    -> Extent Size Big Small height width)
-> WeakenWide height width Size Big Small
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Big Small height width
forall height width. height -> width -> Tall height width
tall height
h width
w)
      ((Extent Size Small Big height width
 -> Extent Size Big Big height width)
-> WeakenWide height width Size Big Big
forall height width meas vert horiz.
(Extent meas Small horiz height width
 -> Extent meas vert horiz height width)
-> WeakenWide height width meas vert horiz
WeakenWide ((Extent Size Small Big height width
  -> Extent Size Big Big height width)
 -> WeakenWide height width Size Big Big)
-> (Extent Size Small Big height width
    -> Extent Size Big Big height width)
-> WeakenWide height width Size Big Big
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Big Big height width
forall height width. height -> width -> General height width
general height
h width
w)


newtype GenToTall height width meas vert horiz =
   GenToTall {
      GenToTall height width meas vert horiz
-> Extent meas vert horiz height width
-> Extent Size Big horiz height width
getGenToTall ::
         Extent meas vert horiz height width ->
         Extent Size Big horiz height width
   }

genToTall :: (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz height width -> Extent Size Big horiz height width
genToTall :: Extent meas vert horiz height width
-> Extent Size Big horiz height width
genToTall =
   GenToTall height width meas vert horiz
-> Extent meas vert horiz height width
-> Extent Size Big horiz height width
forall height width meas vert horiz.
GenToTall height width meas vert horiz
-> Extent meas vert horiz height width
-> Extent Size Big horiz height width
getGenToTall (GenToTall height width meas vert horiz
 -> Extent meas vert horiz height width
 -> Extent Size Big horiz height width)
-> GenToTall height width meas vert horiz
-> Extent meas vert horiz height width
-> Extent Size Big horiz height width
forall a b. (a -> b) -> a -> b
$
   GenToTall height width Shape Small Small
-> GenToTall height width Size Small Small
-> GenToTall height width Size Small Big
-> GenToTall height width Size Big Small
-> GenToTall height width Size Big Big
-> GenToTall height width meas vert horiz
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f Shape Small Small
-> f Size Small Small
-> f Size Small Big
-> f Size Big Small
-> f Size Big Big
-> f meas vert horiz
switchTagTriple
      ((Extent Shape Small Small height width
 -> Extent Size Big Small height width)
-> GenToTall height width Shape Small Small
forall height width meas vert horiz.
(Extent meas vert horiz height width
 -> Extent Size Big horiz height width)
-> GenToTall height width meas vert horiz
GenToTall ((Extent Shape Small Small height width
  -> Extent Size Big Small height width)
 -> GenToTall height width Shape Small Small)
-> (Extent Shape Small Small height width
    -> Extent Size Big Small height width)
-> GenToTall height width Shape Small Small
forall a b. (a -> b) -> a -> b
$ \(Square height
s) -> height -> height -> Tall height height
forall height width. height -> width -> Tall height width
tall height
s height
s)
      ((Extent Size Small Small height width
 -> Extent Size Big Small height width)
-> GenToTall height width Size Small Small
forall height width meas vert horiz.
(Extent meas vert horiz height width
 -> Extent Size Big horiz height width)
-> GenToTall height width meas vert horiz
GenToTall ((Extent Size Small Small height width
  -> Extent Size Big Small height width)
 -> GenToTall height width Size Small Small)
-> (Extent Size Small Small height width
    -> Extent Size Big Small height width)
-> GenToTall height width Size Small Small
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Big Small height width
forall height width. height -> width -> Tall height width
tall height
h width
w)
      ((Extent Size Small Big height width
 -> Extent Size Big Big height width)
-> GenToTall height width Size Small Big
forall height width meas vert horiz.
(Extent meas vert horiz height width
 -> Extent Size Big horiz height width)
-> GenToTall height width meas vert horiz
GenToTall ((Extent Size Small Big height width
  -> Extent Size Big Big height width)
 -> GenToTall height width Size Small Big)
-> (Extent Size Small Big height width
    -> Extent Size Big Big height width)
-> GenToTall height width Size Small Big
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Big Big height width
forall height width. height -> width -> General height width
general height
h width
w)
      ((Extent Size Big Small height width
 -> Extent Size Big Small height width)
-> GenToTall height width Size Big Small
forall height width meas vert horiz.
(Extent meas vert horiz height width
 -> Extent Size Big horiz height width)
-> GenToTall height width meas vert horiz
GenToTall Extent Size Big Small height width
-> Extent Size Big Small height width
forall a. a -> a
id)
      ((Extent Size Big Big height width
 -> Extent Size Big Big height width)
-> GenToTall height width Size Big Big
forall height width meas vert horiz.
(Extent meas vert horiz height width
 -> Extent Size Big horiz height width)
-> GenToTall height width meas vert horiz
GenToTall Extent Size Big Big height width
-> Extent Size Big Big height width
forall a. a -> a
id)

newtype GenToWide height width meas vert horiz =
   GenToWide {
      GenToWide height width meas vert horiz
-> Extent meas vert horiz height width
-> Extent Size vert Big height width
getGenToWide ::
         Extent meas vert horiz height width ->
         Extent Size vert Big height width
   }

genToWide :: (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz height width -> Extent Size vert Big height width
genToWide :: Extent meas vert horiz height width
-> Extent Size vert Big height width
genToWide =
   GenToWide height width meas vert horiz
-> Extent meas vert horiz height width
-> Extent Size vert Big height width
forall height width meas vert horiz.
GenToWide height width meas vert horiz
-> Extent meas vert horiz height width
-> Extent Size vert Big height width
getGenToWide (GenToWide height width meas vert horiz
 -> Extent meas vert horiz height width
 -> Extent Size vert Big height width)
-> GenToWide height width meas vert horiz
-> Extent meas vert horiz height width
-> Extent Size vert Big height width
forall a b. (a -> b) -> a -> b
$
   GenToWide height width Shape Small Small
-> GenToWide height width Size Small Small
-> GenToWide height width Size Small Big
-> GenToWide height width Size Big Small
-> GenToWide height width Size Big Big
-> GenToWide height width meas vert horiz
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f Shape Small Small
-> f Size Small Small
-> f Size Small Big
-> f Size Big Small
-> f Size Big Big
-> f meas vert horiz
switchTagTriple
      ((Extent Shape Small Small height width
 -> Extent Size Small Big height width)
-> GenToWide height width Shape Small Small
forall height width meas vert horiz.
(Extent meas vert horiz height width
 -> Extent Size vert Big height width)
-> GenToWide height width meas vert horiz
GenToWide ((Extent Shape Small Small height width
  -> Extent Size Small Big height width)
 -> GenToWide height width Shape Small Small)
-> (Extent Shape Small Small height width
    -> Extent Size Small Big height width)
-> GenToWide height width Shape Small Small
forall a b. (a -> b) -> a -> b
$ \(Square height
s) -> height -> height -> Wide height height
forall height width. height -> width -> Wide height width
wide height
s height
s)
      ((Extent Size Small Small height width
 -> Extent Size Small Big height width)
-> GenToWide height width Size Small Small
forall height width meas vert horiz.
(Extent meas vert horiz height width
 -> Extent Size vert Big height width)
-> GenToWide height width meas vert horiz
GenToWide ((Extent Size Small Small height width
  -> Extent Size Small Big height width)
 -> GenToWide height width Size Small Small)
-> (Extent Size Small Small height width
    -> Extent Size Small Big height width)
-> GenToWide height width Size Small Small
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Small Big height width
forall height width. height -> width -> Wide height width
wide height
h width
w)
      ((Extent Size Small Big height width
 -> Extent Size Small Big height width)
-> GenToWide height width Size Small Big
forall height width meas vert horiz.
(Extent meas vert horiz height width
 -> Extent Size vert Big height width)
-> GenToWide height width meas vert horiz
GenToWide Extent Size Small Big height width
-> Extent Size Small Big height width
forall a. a -> a
id)
      ((Extent Size Big Small height width
 -> Extent Size Big Big height width)
-> GenToWide height width Size Big Small
forall height width meas vert horiz.
(Extent meas vert horiz height width
 -> Extent Size vert Big height width)
-> GenToWide height width meas vert horiz
GenToWide ((Extent Size Big Small height width
  -> Extent Size Big Big height width)
 -> GenToWide height width Size Big Small)
-> (Extent Size Big Small height width
    -> Extent Size Big Big height width)
-> GenToWide height width Size Big Small
forall a b. (a -> b) -> a -> b
$ \(Separate height
h width
w) -> height -> width -> Extent Size Big Big height width
forall height width. height -> width -> General height width
general height
h width
w)
      ((Extent Size Big Big height width
 -> Extent Size Big Big height width)
-> GenToWide height width Size Big Big
forall height width meas vert horiz.
(Extent meas vert horiz height width
 -> Extent Size vert Big height width)
-> GenToWide height width meas vert horiz
GenToWide Extent Size Big Big height width
-> Extent Size Big Big height width
forall a. a -> a
id)


newtype Accessor a height width meas vert horiz =
   Accessor {Accessor a height width meas vert horiz
-> Extent meas vert horiz height width -> a
getAccessor :: Extent meas vert horiz height width -> a}

squareSize :: Square shape -> shape
squareSize :: Square shape -> shape
squareSize (Square shape
s) = shape
s

height ::
   (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz height width -> height
height :: Extent meas vert horiz height width -> height
height (Square height
s) = height
s
height (Separate height
h width
_w) = height
h

width ::
   (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz height width -> width
width :: Extent meas vert horiz height width -> width
width (Square height
s) = height
width
s
width (Separate height
_h width
w) = width
w


dimensions ::
   (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz height width -> (height,width)
dimensions :: Extent meas vert horiz height width -> (height, width)
dimensions Extent meas vert horiz height width
x = (Extent meas vert horiz height width -> height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
height Extent meas vert horiz height width
x, Extent meas vert horiz height width -> width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
width Extent meas vert horiz height width
x)


toGeneral ::
   (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz height width -> General height width
toGeneral :: Extent meas vert horiz height width -> General height width
toGeneral Extent meas vert horiz height width
x = height -> width -> General height width
forall height width. height -> width -> General height width
general (Extent meas vert horiz height width -> height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
height Extent meas vert horiz height width
x) (Extent meas vert horiz height width -> width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
width Extent meas vert horiz height width
x)

fromSquare ::
   (Measure meas, C vert, C horiz) =>
   Square size -> Extent meas vert horiz size size
fromSquare :: Square size -> Extent meas vert horiz size size
fromSquare (Square size
s) = size -> Extent meas vert horiz size size
forall meas vert horiz sh.
(Measure meas, C vert, C horiz) =>
sh -> Extent meas vert horiz sh sh
genSquare size
s

fromSquareLiberal ::
   (Measure meas, C vert, C horiz) =>
   Extent Shape Small Small height width ->
   Extent meas vert horiz height width
fromSquareLiberal :: Extent Shape Small Small height width
-> Extent meas vert horiz height width
fromSquareLiberal (Square height
h) = height -> Extent meas vert horiz height height
forall meas vert horiz sh.
(Measure meas, C vert, C horiz) =>
sh -> Extent meas vert horiz sh sh
genSquare height
h

fromLiberalSquare :: (C vert, C horiz) =>
   LiberalSquare height width ->
   Extent Size vert horiz height width
fromLiberalSquare :: LiberalSquare height width -> Extent Size vert horiz height width
fromLiberalSquare (Separate height
h width
w) = height -> width -> Extent Size vert horiz height width
forall vert horiz height width.
(C vert, C horiz) =>
height -> width -> Extent Size vert horiz height width
genLiberalSquare height
h width
w

squareFromFull ::
   (Measure meas, C vert, C horiz, Eq size) =>
   Extent meas vert horiz size size -> Square size
squareFromFull :: Extent meas vert horiz size size -> Square size
squareFromFull Extent meas vert horiz size size
x =
   let size :: size
size = Extent meas vert horiz size size -> size
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
height Extent meas vert horiz size size
x
   in if size
size size -> size -> Bool
forall a. Eq a => a -> a -> Bool
== Extent meas vert horiz size size -> size
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
width Extent meas vert horiz size size
x
         then size -> Square size
forall size. size -> Extent Shape Small Small size size
square size
size
         else String -> Square size
forall a. HasCallStack => String -> a
error String
"Extent.squareFromFull: no square shape"

liberalSquareFromFull ::
   (Measure meas, C vert, C horiz, Shape.C height, Shape.C width) =>
   Extent meas vert horiz height width -> LiberalSquare height width
liberalSquareFromFull :: Extent meas vert horiz height width -> LiberalSquare height width
liberalSquareFromFull (Square height
s) = height -> height -> Extent Size Small Small height height
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate height
s height
s
liberalSquareFromFull (Separate height
h width
w) =
   if height -> Int
forall sh. C sh => sh -> Int
Shape.size height
h Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== width -> Int
forall sh. C sh => sh -> Int
Shape.size width
w
      then height -> width -> LiberalSquare height width
forall height width. height -> width -> LiberalSquare height width
liberalSquare height
h width
w
      else String -> LiberalSquare height width
forall a. HasCallStack => String -> a
error String
"Extent.liberalSquareFromFull: no square shape"


transpose ::
   (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz height width ->
   Extent meas horiz vert width height
transpose :: Extent meas vert horiz height width
-> Extent meas horiz vert width height
transpose (Square height
s) = height -> Extent Shape Small Small height height
forall size. size -> Extent Shape Small Small size size
Square height
s
transpose (Separate height
h width
w) = width -> height -> Extent Size horiz vert width height
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate width
w height
h


instance
   (Measure meas, C vert, C horiz, Eq height, Eq width) =>
      Eq (Extent meas vert horiz height width) where
   Square height
a == :: Extent meas vert horiz height width
-> Extent meas vert horiz height width -> Bool
== Square height
b  =  height
aheight -> height -> Bool
forall a. Eq a => a -> a -> Bool
==height
b
   Separate height
h0 width
w0 == Separate height
h1 width
w1  = height
h0height -> height -> Bool
forall a. Eq a => a -> a -> Bool
==height
h1 Bool -> Bool -> Bool
&& width
w0width -> width -> Bool
forall a. Eq a => a -> a -> Bool
==width
w1


instance
   (Measure meas, C vert, C horiz, Show height, Show width) =>
      Show (Extent meas vert horiz height width) where
   showsPrec :: Int -> Extent meas vert horiz height width -> ShowS
showsPrec Int
prec x :: Extent meas vert horiz height width
x@(Square height
_) = Int -> Extent Shape Small Small height width -> ShowS
forall height width.
Show height =>
Int -> Extent Shape Small Small height width -> ShowS
showsPrecSquare Int
prec Extent meas vert horiz height width
Extent Shape Small Small height width
x
   showsPrec Int
prec x :: Extent meas vert horiz height width
x@(Separate height
_ width
_) =
      (Accessor ShowS height width meas vert horiz
 -> Extent meas vert horiz height width -> ShowS)
-> Extent meas vert horiz height width
-> Accessor ShowS height width meas vert horiz
-> ShowS
forall a b c. (a -> b -> c) -> b -> a -> c
flip Accessor ShowS height width meas vert horiz
-> Extent meas vert horiz height width -> ShowS
forall a height width meas vert horiz.
Accessor a height width meas vert horiz
-> Extent meas vert horiz height width -> a
getAccessor Extent meas vert horiz height width
x (Accessor ShowS height width meas vert horiz -> ShowS)
-> Accessor ShowS height width meas vert horiz -> ShowS
forall a b. (a -> b) -> a -> b
$
      Accessor ShowS height width meas Small Small
-> Accessor ShowS height width meas Small Big
-> Accessor ShowS height width meas Big Small
-> Accessor ShowS height width meas Big Big
-> Accessor ShowS height width meas vert horiz
forall vert horiz (f :: * -> * -> *).
(C vert, C horiz) =>
f Small Small
-> f Small Big -> f Big Small -> f Big Big -> f vert horiz
switchTagPair
         ((Extent meas Small Small height width -> ShowS)
-> Accessor ShowS height width meas Small Small
forall a height width meas vert horiz.
(Extent meas vert horiz height width -> a)
-> Accessor a height width meas vert horiz
Accessor ((Extent meas Small Small height width -> ShowS)
 -> Accessor ShowS height width meas Small Small)
-> (Extent meas Small Small height width -> ShowS)
-> Accessor ShowS height width meas Small Small
forall a b. (a -> b) -> a -> b
$ String -> Int -> Extent meas Small Small height width -> ShowS
forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
String -> Int -> Extent meas vert horiz height width -> ShowS
showsPrecAny String
"Extent.liberalSquare" Int
prec)
         ((Extent meas Small Big height width -> ShowS)
-> Accessor ShowS height width meas Small Big
forall a height width meas vert horiz.
(Extent meas vert horiz height width -> a)
-> Accessor a height width meas vert horiz
Accessor ((Extent meas Small Big height width -> ShowS)
 -> Accessor ShowS height width meas Small Big)
-> (Extent meas Small Big height width -> ShowS)
-> Accessor ShowS height width meas Small Big
forall a b. (a -> b) -> a -> b
$ String -> Int -> Extent meas Small Big height width -> ShowS
forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
String -> Int -> Extent meas vert horiz height width -> ShowS
showsPrecAny String
"Extent.wide" Int
prec)
         ((Extent meas Big Small height width -> ShowS)
-> Accessor ShowS height width meas Big Small
forall a height width meas vert horiz.
(Extent meas vert horiz height width -> a)
-> Accessor a height width meas vert horiz
Accessor ((Extent meas Big Small height width -> ShowS)
 -> Accessor ShowS height width meas Big Small)
-> (Extent meas Big Small height width -> ShowS)
-> Accessor ShowS height width meas Big Small
forall a b. (a -> b) -> a -> b
$ String -> Int -> Extent meas Big Small height width -> ShowS
forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
String -> Int -> Extent meas vert horiz height width -> ShowS
showsPrecAny String
"Extent.tall" Int
prec)
         ((Extent meas Big Big height width -> ShowS)
-> Accessor ShowS height width meas Big Big
forall a height width meas vert horiz.
(Extent meas vert horiz height width -> a)
-> Accessor a height width meas vert horiz
Accessor ((Extent meas Big Big height width -> ShowS)
 -> Accessor ShowS height width meas Big Big)
-> (Extent meas Big Big height width -> ShowS)
-> Accessor ShowS height width meas Big Big
forall a b. (a -> b) -> a -> b
$ String -> Int -> Extent meas Big Big height width -> ShowS
forall meas vert horiz height width.
(Measure meas, C vert, C horiz, Show height, Show width) =>
String -> Int -> Extent meas vert horiz height width -> ShowS
showsPrecAny String
"Extent.general" Int
prec)

showsPrecSquare ::
   (Show height) =>
   Int -> Extent Shape Small Small height width -> ShowS
showsPrecSquare :: Int -> Extent Shape Small Small height width -> ShowS
showsPrecSquare Int
p Extent Shape Small Small height width
x =
   Bool -> ShowS -> ShowS
showParen (Int
pInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
   String -> ShowS
showString String
"Extent.square " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> height -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 (Extent Shape Small Small height width -> height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
height Extent Shape Small Small height width
x)

showsPrecAny ::
   (Measure meas, C vert, C horiz, Show height, Show width) =>
   String -> Int -> Extent meas vert horiz height width -> ShowS
showsPrecAny :: String -> Int -> Extent meas vert horiz height width -> ShowS
showsPrecAny String
name Int
p Extent meas vert horiz height width
x =
   Bool -> ShowS -> ShowS
showParen (Int
pInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
   String -> ShowS
showString String
name ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   String -> ShowS
showString String
" " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> height -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 (Extent meas vert horiz height width -> height
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> height
height Extent meas vert horiz height width
x) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   String -> ShowS
showString String
" " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> width -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 (Extent meas vert horiz height width -> width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
width Extent meas vert horiz height width
x)


widen ::
   (C vert) =>
   widthB ->
   Extent Size vert Big height widthA -> Extent Size vert Big height widthB
widen :: widthB
-> Extent Size vert Big height widthA
-> Extent Size vert Big height widthB
widen widthB
w (Separate height
h widthA
_) = height -> widthB -> Extent Size vert Big height widthB
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate height
h widthB
w

reduceWideHeight ::
   (C vert) =>
   heightB ->
   Extent Size vert Big heightA width -> Extent Size vert Big heightB width
reduceWideHeight :: heightB
-> Extent Size vert Big heightA width
-> Extent Size vert Big heightB width
reduceWideHeight heightB
h (Separate heightA
_ width
w) = heightB -> width -> Extent Size vert Big heightB width
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate heightB
h width
w


reduceConsistent ::
   (Measure meas, C vert, C horiz) =>
   height -> width ->
   Extent meas vert horiz height width -> Extent meas vert horiz height width
reduceConsistent :: height
-> width
-> Extent meas vert horiz height width
-> Extent meas vert horiz height width
reduceConsistent height
h width
_ (Square height
_) = height -> Extent Shape Small Small height height
forall size. size -> Extent Shape Small Small size size
Square height
h
reduceConsistent height
h width
w (Separate height
_ width
_) = height -> width -> Extent Size vert horiz height width
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate height
h width
w

mapHeight ::
   (C vert, C horiz) =>
   (heightA -> heightB) ->
   Extent Size vert horiz heightA width -> Extent Size vert horiz heightB width
mapHeight :: (heightA -> heightB)
-> Extent Size vert horiz heightA width
-> Extent Size vert horiz heightB width
mapHeight heightA -> heightB
f (Separate heightA
h width
w) = heightB -> width -> Extent Size vert horiz heightB width
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate (heightA -> heightB
f heightA
h) width
w

mapWidth ::
   (C vert, C horiz) =>
   (widthA -> widthB) ->
   Extent Size vert horiz height widthA -> Extent Size vert horiz height widthB
mapWidth :: (widthA -> widthB)
-> Extent Size vert horiz height widthA
-> Extent Size vert horiz height widthB
mapWidth widthA -> widthB
f (Separate height
h widthA
w) = height -> widthB -> Extent Size vert horiz height widthB
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate height
h (widthA -> widthB
f widthA
w)

mapSquareSize :: (shA -> shB) -> Square shA -> Square shB
mapSquareSize :: (shA -> shB) -> Square shA -> Square shB
mapSquareSize shA -> shB
f (Square shA
s) = shB -> Square shB
forall size. size -> Extent Shape Small Small size size
Square (shA -> shB
f shA
s)


mapWrap ::
   (Measure meas, C vert, C horiz) =>
   (height -> f height) ->
   (width -> f width) ->
   Extent meas vert horiz height width ->
   Extent meas vert horiz (f height) (f width)
mapWrap :: (height -> f height)
-> (width -> f width)
-> Extent meas vert horiz height width
-> Extent meas vert horiz (f height) (f width)
mapWrap height -> f height
fh width -> f width
_ (Square height
h) = f height -> Extent Shape Small Small (f height) (f height)
forall size. size -> Extent Shape Small Small size size
Square (height -> f height
fh height
h)
mapWrap height -> f height
fh width -> f width
fw (Separate height
h width
w) = f height -> f width -> Extent Size vert horiz (f height) (f width)
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate (height -> f height
fh height
h) (width -> f width
fw width
w)

{- only admissible since GHC-7.8
mapUnwrap ::
   (Measure meas, C vert, C horiz) =>
   (f height -> height) ->
   (f width -> width) ->
   Extent meas vert horiz (f height) (f width) ->
   Extent meas vert horiz height width
mapUnwrap fh fw =
   getAdapt $
   switchTagPair
      (Adapt $ \(Square h) -> Square (fh h))
      (Adapt $ \(Wide h w) -> Wide (fh h) (fw w))
      (Adapt $ \(Tall h w) -> Tall (fh h) (fw w))
      (Adapt $ \(General h w) -> General (fh h) (fw w))
-}

recheck ::
   (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz (Unchecked height) (Unchecked width) ->
   Extent meas vert horiz height width
recheck :: Extent meas vert horiz (Unchecked height) (Unchecked width)
-> Extent meas vert horiz height width
recheck (Square Unchecked height
h) = height -> Extent Shape Small Small height height
forall size. size -> Extent Shape Small Small size size
Square (Unchecked height -> height
forall sh. Unchecked sh -> sh
deconsUnchecked Unchecked height
h)
recheck (Separate Unchecked height
h Unchecked width
w) = height -> width -> Extent Size vert horiz height width
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate (Unchecked height -> height
forall sh. Unchecked sh -> sh
deconsUnchecked Unchecked height
h) (Unchecked width -> width
forall sh. Unchecked sh -> sh
deconsUnchecked Unchecked width
w)

recheckAppend ::
   (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz
      (Unchecked heightA ::+ Unchecked heightB)
      (Unchecked widthA  ::+ Unchecked widthB) ->
   Extent meas vert horiz (heightA::+heightB) (widthA::+widthB)
recheckAppend :: Extent
  meas
  vert
  horiz
  (Unchecked heightA ::+ Unchecked heightB)
  (Unchecked widthA ::+ Unchecked widthB)
-> Extent meas vert horiz (heightA ::+ heightB) (widthA ::+ widthB)
recheckAppend (Square (Unchecked heightA
ha::+Unchecked heightB
hb)) =
   (heightA ::+ heightB)
-> Extent
     Shape Small Small (heightA ::+ heightB) (heightA ::+ heightB)
forall size. size -> Extent Shape Small Small size size
Square (Unchecked heightA -> heightA
forall sh. Unchecked sh -> sh
deconsUnchecked Unchecked heightA
ha heightA -> heightB -> heightA ::+ heightB
forall sh0 sh1. sh0 -> sh1 -> sh0 ::+ sh1
::+ Unchecked heightB -> heightB
forall sh. Unchecked sh -> sh
deconsUnchecked Unchecked heightB
hb)
recheckAppend (Separate (Unchecked heightA
ha::+Unchecked heightB
hb) (Unchecked widthA
wa::+Unchecked widthB
wb)) =
   (heightA ::+ heightB)
-> (widthA ::+ widthB)
-> Extent Size vert horiz (heightA ::+ heightB) (widthA ::+ widthB)
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate
      (Unchecked heightA -> heightA
forall sh. Unchecked sh -> sh
deconsUnchecked Unchecked heightA
ha heightA -> heightB -> heightA ::+ heightB
forall sh0 sh1. sh0 -> sh1 -> sh0 ::+ sh1
::+ Unchecked heightB -> heightB
forall sh. Unchecked sh -> sh
deconsUnchecked Unchecked heightB
hb)
      (Unchecked widthA -> widthA
forall sh. Unchecked sh -> sh
deconsUnchecked Unchecked widthA
wa widthA -> widthB -> widthA ::+ widthB
forall sh0 sh1. sh0 -> sh1 -> sh0 ::+ sh1
::+ Unchecked widthB -> widthB
forall sh. Unchecked sh -> sh
deconsUnchecked Unchecked widthB
wb)

fuse ::
   (Measure meas, C vert, C horiz, Eq fuse) =>
   Extent meas vert horiz height fuse ->
   Extent meas vert horiz fuse width ->
   Maybe (Extent meas vert horiz height width)
fuse :: Extent meas vert horiz height fuse
-> Extent meas vert horiz fuse width
-> Maybe (Extent meas vert horiz height width)
fuse (Square height
s0) (Square fuse
s1) = Bool
-> Extent Shape Small Small height height
-> Maybe (Extent Shape Small Small height height)
forall a. Bool -> a -> Maybe a
toMaybe (height
s0height -> height -> Bool
forall a. Eq a => a -> a -> Bool
==fuse
height
s1) (Extent Shape Small Small height height
 -> Maybe (Extent Shape Small Small height height))
-> Extent Shape Small Small height height
-> Maybe (Extent Shape Small Small height height)
forall a b. (a -> b) -> a -> b
$ height -> Extent Shape Small Small height height
forall size. size -> Extent Shape Small Small size size
Square height
s0
fuse (Separate height
h fuse
f0) (Separate fuse
f1 width
w) = Bool
-> Extent Size vert horiz height width
-> Maybe (Extent Size vert horiz height width)
forall a. Bool -> a -> Maybe a
toMaybe (fuse
f0fuse -> fuse -> Bool
forall a. Eq a => a -> a -> Bool
==fuse
f1) (Extent Size vert horiz height width
 -> Maybe (Extent Size vert horiz height width))
-> Extent Size vert horiz height width
-> Maybe (Extent Size vert horiz height width)
forall a b. (a -> b) -> a -> b
$ height -> width -> Extent Size vert horiz height width
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate height
h width
w

relaxMeasureWith ::
   (Measure measA, Measure measB,
    MultiplyMeasure measA measB ~ measC,
    C vert, C horiz) =>
   Extent measA vertA horizA heightA widthA ->
   Extent measB vert horiz height width ->
   Extent measC vert horiz height width
relaxMeasureWith :: Extent measA vertA horizA heightA widthA
-> Extent measB vert horiz height width
-> Extent measC vert horiz height width
relaxMeasureWith (Square heightA
_) = Extent measB vert horiz height width
-> Extent measC vert horiz height width
forall a. a -> a
id
relaxMeasureWith (Separate heightA
_ widthA
_) = Extent measB vert horiz height width
-> Extent measC vert horiz height width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width
-> Extent Size vert horiz height width
relaxMeasure


kronecker ::
   (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz heightA widthA ->
   Extent meas vert horiz heightB widthB ->
   Extent meas vert horiz (heightA,heightB) (widthA,widthB)
kronecker :: Extent meas vert horiz heightA widthA
-> Extent meas vert horiz heightB widthB
-> Extent meas vert horiz (heightA, heightB) (widthA, widthB)
kronecker = (heightA -> heightB -> (heightA, heightB))
-> (widthA -> widthB -> (widthA, widthB))
-> Extent meas vert horiz heightA widthA
-> Extent meas vert horiz heightB widthB
-> Extent meas vert horiz (heightA, heightB) (widthA, widthB)
forall meas vert horiz heightA heightB (f :: * -> * -> *) widthA
       widthB.
(Measure meas, C vert, C horiz) =>
(heightA -> heightB -> f heightA heightB)
-> (widthA -> widthB -> f widthA widthB)
-> Extent meas vert horiz heightA widthA
-> Extent meas vert horiz heightB widthB
-> Extent meas vert horiz (f heightA heightB) (f widthA widthB)
stackGen (,) (,)



{-
Tag table for 'beside'.

Small Small  Small Small -> Small Big
Small Small  Small Big   -> Small Big
Small Small  Big   Small -> Small Big
Small Small  Big   Big   -> Small Big
Small Big    Small Small -> Small Big
Small Big    Small Big   -> Small Big
Small Big    Big   Small -> Small Big
Small Big    Big   Big   -> Small Big
Big   Small  Small Small -> Small Big
Big   Small  Small Big   -> Small Big
Big   Small  Big   Small -> Big   Big
Big   Small  Big   Big   -> Big   Big
Big   Big    Small Small -> Small Big
Big   Big    Small Big   -> Small Big
Big   Big    Big   Small -> Big   Big
Big   Big    Big   Big   -> Big   Big
-}
newtype AppendMode vertA vertB vertC height widthA widthB =
   AppendMode (
      Extent Size vertA Big height widthA ->
      Extent Size vertB Big height widthB ->
      Extent Size vertC Big height (widthA::+widthB)
   )

appendLeftAux ::
   (C vertA, C vertB) => AppendMode vertA vertB vertA height widthA widthB
appendLeftAux :: AppendMode vertA vertB vertA height widthA widthB
appendLeftAux =
   (Extent Size vertA Big height widthA
 -> Extent Size vertB Big height widthB
 -> Extent Size vertA Big height (widthA ::+ widthB))
-> AppendMode vertA vertB vertA height widthA widthB
forall vertA vertB vertC height widthA widthB.
(Extent Size vertA Big height widthA
 -> Extent Size vertB Big height widthB
 -> Extent Size vertC Big height (widthA ::+ widthB))
-> AppendMode vertA vertB vertC height widthA widthB
AppendMode ((Extent Size vertA Big height widthA
  -> Extent Size vertB Big height widthB
  -> Extent Size vertA Big height (widthA ::+ widthB))
 -> AppendMode vertA vertB vertA height widthA widthB)
-> (Extent Size vertA Big height widthA
    -> Extent Size vertB Big height widthB
    -> Extent Size vertA Big height (widthA ::+ widthB))
-> AppendMode vertA vertB vertA height widthA widthB
forall a b. (a -> b) -> a -> b
$ \Extent Size vertA Big height widthA
extentA Extent Size vertB Big height widthB
extentB ->
      (widthA ::+ widthB)
-> Extent Size vertA Big height widthA
-> Extent Size vertA Big height (widthA ::+ widthB)
forall vert widthB height widthA.
C vert =>
widthB
-> Extent Size vert Big height widthA
-> Extent Size vert Big height widthB
widen (Extent Size vertA Big height widthA -> widthA
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
width Extent Size vertA Big height widthA
extentA widthA -> widthB -> widthA ::+ widthB
forall sh0 sh1. sh0 -> sh1 -> sh0 ::+ sh1
::+ Extent Size vertB Big height widthB -> widthB
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
width Extent Size vertB Big height widthB
extentB) Extent Size vertA Big height widthA
extentA

appendSame :: (C vert) => AppendMode vert vert vert height widthA widthB
appendSame :: AppendMode vert vert vert height widthA widthB
appendSame = AppendMode vert vert vert height widthA widthB
forall vertA vertB height widthA widthB.
(C vertA, C vertB) =>
AppendMode vertA vertB vertA height widthA widthB
appendLeftAux

appendLeft :: (C vert) => AppendMode vert Big vert height widthA widthB
appendLeft :: AppendMode vert Big vert height widthA widthB
appendLeft = AppendMode vert Big vert height widthA widthB
forall vertA vertB height widthA widthB.
(C vertA, C vertB) =>
AppendMode vertA vertB vertA height widthA widthB
appendLeftAux

appendRight :: (C vert) => AppendMode Big vert vert height widthA widthB
appendRight :: AppendMode Big vert vert height widthA widthB
appendRight =
   (Extent Size Big Big height widthA
 -> Extent Size vert Big height widthB
 -> Extent Size vert Big height (widthA ::+ widthB))
-> AppendMode Big vert vert height widthA widthB
forall vertA vertB vertC height widthA widthB.
(Extent Size vertA Big height widthA
 -> Extent Size vertB Big height widthB
 -> Extent Size vertC Big height (widthA ::+ widthB))
-> AppendMode vertA vertB vertC height widthA widthB
AppendMode ((Extent Size Big Big height widthA
  -> Extent Size vert Big height widthB
  -> Extent Size vert Big height (widthA ::+ widthB))
 -> AppendMode Big vert vert height widthA widthB)
-> (Extent Size Big Big height widthA
    -> Extent Size vert Big height widthB
    -> Extent Size vert Big height (widthA ::+ widthB))
-> AppendMode Big vert vert height widthA widthB
forall a b. (a -> b) -> a -> b
$ \Extent Size Big Big height widthA
extentA Extent Size vert Big height widthB
extentB ->
      (widthA ::+ widthB)
-> Extent Size vert Big height widthB
-> Extent Size vert Big height (widthA ::+ widthB)
forall vert widthB height widthA.
C vert =>
widthB
-> Extent Size vert Big height widthA
-> Extent Size vert Big height widthB
widen (Extent Size Big Big height widthA -> widthA
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
width Extent Size Big Big height widthA
extentA widthA -> widthB -> widthA ::+ widthB
forall sh0 sh1. sh0 -> sh1 -> sh0 ::+ sh1
::+ Extent Size vert Big height widthB -> widthB
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> width
width Extent Size vert Big height widthB
extentB) Extent Size vert Big height widthB
extentB

type family Append a b
type instance Append Small b = Small
type instance Append Big   b = b

newtype
   AppendAny vertB height widthA widthB vertA =
      AppendAny {
         AppendAny vertB height widthA widthB vertA
-> AppendMode vertA vertB (Append vertA vertB) height widthA widthB
getAppendAny ::
            AppendMode vertA vertB (Append vertA vertB) height widthA widthB
      }

appendAny ::
   (C vertA, C vertB) =>
   AppendMode vertA vertB (Append vertA vertB) height widthA widthB
appendAny :: AppendMode vertA vertB (Append vertA vertB) height widthA widthB
appendAny =
   AppendAny vertB height widthA widthB vertA
-> AppendMode vertA vertB (Append vertA vertB) height widthA widthB
forall vertB height widthA widthB vertA.
AppendAny vertB height widthA widthB vertA
-> AppendMode vertA vertB (Append vertA vertB) height widthA widthB
getAppendAny (AppendAny vertB height widthA widthB vertA
 -> AppendMode
      vertA vertB (Append vertA vertB) height widthA widthB)
-> AppendAny vertB height widthA widthB vertA
-> AppendMode vertA vertB (Append vertA vertB) height widthA widthB
forall a b. (a -> b) -> a -> b
$ AppendAny vertB height widthA widthB Small
-> AppendAny vertB height widthA widthB Big
-> AppendAny vertB height widthA widthB vertA
forall tag (f :: * -> *). C tag => f Small -> f Big -> f tag
switchTag (AppendMode Small vertB (Append Small vertB) height widthA widthB
-> AppendAny vertB height widthA widthB Small
forall vertB height widthA widthB vertA.
AppendMode vertA vertB (Append vertA vertB) height widthA widthB
-> AppendAny vertB height widthA widthB vertA
AppendAny AppendMode Small vertB (Append Small vertB) height widthA widthB
forall vertA vertB height widthA widthB.
(C vertA, C vertB) =>
AppendMode vertA vertB vertA height widthA widthB
appendLeftAux) (AppendMode Big vertB (Append Big vertB) height widthA widthB
-> AppendAny vertB height widthA widthB Big
forall vertB height widthA widthB vertA.
AppendMode vertA vertB (Append vertA vertB) height widthA widthB
-> AppendAny vertB height widthA widthB vertA
AppendAny AppendMode Big vertB (Append Big vertB) height widthA widthB
forall vert height widthA widthB.
C vert =>
AppendMode Big vert vert height widthA widthB
appendRight)


stack ::
   (Measure meas, C vert, C horiz) =>
   Extent meas vert horiz heightA widthA ->
   Extent meas vert horiz heightB widthB ->
   Extent meas vert horiz (heightA::+heightB) (widthA::+widthB)
stack :: Extent meas vert horiz heightA widthA
-> Extent meas vert horiz heightB widthB
-> Extent meas vert horiz (heightA ::+ heightB) (widthA ::+ widthB)
stack = (heightA -> heightB -> heightA ::+ heightB)
-> (widthA -> widthB -> widthA ::+ widthB)
-> Extent meas vert horiz heightA widthA
-> Extent meas vert horiz heightB widthB
-> Extent meas vert horiz (heightA ::+ heightB) (widthA ::+ widthB)
forall meas vert horiz heightA heightB (f :: * -> * -> *) widthA
       widthB.
(Measure meas, C vert, C horiz) =>
(heightA -> heightB -> f heightA heightB)
-> (widthA -> widthB -> f widthA widthB)
-> Extent meas vert horiz heightA widthA
-> Extent meas vert horiz heightB widthB
-> Extent meas vert horiz (f heightA heightB) (f widthA widthB)
stackGen heightA -> heightB -> heightA ::+ heightB
forall sh0 sh1. sh0 -> sh1 -> sh0 ::+ sh1
(::+) widthA -> widthB -> widthA ::+ widthB
forall sh0 sh1. sh0 -> sh1 -> sh0 ::+ sh1
(::+)

stackGen ::
   (Measure meas, C vert, C horiz) =>
   (heightA -> heightB -> f heightA heightB) ->
   (widthA -> widthB -> f widthA widthB) ->
   Extent meas vert horiz heightA widthA ->
   Extent meas vert horiz heightB widthB ->
   Extent meas vert horiz (f heightA heightB) (f widthA widthB)
stackGen :: (heightA -> heightB -> f heightA heightB)
-> (widthA -> widthB -> f widthA widthB)
-> Extent meas vert horiz heightA widthA
-> Extent meas vert horiz heightB widthB
-> Extent meas vert horiz (f heightA heightB) (f widthA widthB)
stackGen heightA -> heightB -> f heightA heightB
fh widthA -> widthB -> f widthA widthB
_f (Square heightA
sa) (Square heightB
sb) = f heightA heightB
-> Extent Shape Small Small (f heightA heightB) (f heightA heightB)
forall size. size -> Extent Shape Small Small size size
Square (heightA -> heightB -> f heightA heightB
fh heightA
sa heightB
sb)
stackGen heightA -> heightB -> f heightA heightB
fh widthA -> widthB -> f widthA widthB
fw (Separate heightA
ha widthA
wa) (Separate heightB
hb widthB
wb) =
                              f heightA heightB
-> f widthA widthB
-> Extent Size vert horiz (f heightA heightB) (f widthA widthB)
forall height width vert horiz.
height -> width -> Extent Size vert horiz height width
Separate (heightA -> heightB -> f heightA heightB
fh heightA
ha heightB
hb) (widthA -> widthB -> f widthA widthB
fw widthA
wa widthB
wb)


type family Multiply a b
type instance Multiply Small b = b
type instance Multiply Big   b = Big

type family MultiplyMeasure a b
type instance MultiplyMeasure Shape b = b
type instance MultiplyMeasure Size  b = Size


data TagFact a = C a => TagFact

newtype MultiplyTagLaw b a =
   MultiplyTagLaw {
      MultiplyTagLaw b a
-> TagFact a -> TagFact b -> TagFact (Multiply a b)
getMultiplyTagLaw :: TagFact a -> TagFact b -> TagFact (Multiply a b)
   }

multiplyTagLaw :: TagFact a -> TagFact b -> TagFact (Multiply a b)
multiplyTagLaw :: TagFact a -> TagFact b -> TagFact (Multiply a b)
multiplyTagLaw a :: TagFact a
a@TagFact a
TagFact =
   ((TagFact a -> TagFact b -> TagFact (Multiply a b))
-> TagFact a -> TagFact b -> TagFact (Multiply a b)
forall a b. (a -> b) -> a -> b
$TagFact a
a) ((TagFact a -> TagFact b -> TagFact (Multiply a b))
 -> TagFact b -> TagFact (Multiply a b))
-> (TagFact a -> TagFact b -> TagFact (Multiply a b))
-> TagFact b
-> TagFact (Multiply a b)
forall a b. (a -> b) -> a -> b
$ MultiplyTagLaw b a
-> TagFact a -> TagFact b -> TagFact (Multiply a b)
forall b a.
MultiplyTagLaw b a
-> TagFact a -> TagFact b -> TagFact (Multiply a b)
getMultiplyTagLaw (MultiplyTagLaw b a
 -> TagFact a -> TagFact b -> TagFact (Multiply a b))
-> MultiplyTagLaw b a
-> TagFact a
-> TagFact b
-> TagFact (Multiply a b)
forall a b. (a -> b) -> a -> b
$
   MultiplyTagLaw b Small
-> MultiplyTagLaw b Big -> MultiplyTagLaw b a
forall tag (f :: * -> *). C tag => f Small -> f Big -> f tag
switchTag
      ((TagFact Small -> TagFact b -> TagFact (Multiply Small b))
-> MultiplyTagLaw b Small
forall b a.
(TagFact a -> TagFact b -> TagFact (Multiply a b))
-> MultiplyTagLaw b a
MultiplyTagLaw ((TagFact Small -> TagFact b -> TagFact (Multiply Small b))
 -> MultiplyTagLaw b Small)
-> (TagFact Small -> TagFact b -> TagFact (Multiply Small b))
-> MultiplyTagLaw b Small
forall a b. (a -> b) -> a -> b
$ (TagFact b -> TagFact Small -> TagFact b)
-> TagFact Small -> TagFact b -> TagFact b
forall a b c. (a -> b -> c) -> b -> a -> c
flip TagFact b -> TagFact Small -> TagFact b
forall a b. a -> b -> a
const)
      ((TagFact Big -> TagFact b -> TagFact (Multiply Big b))
-> MultiplyTagLaw b Big
forall b a.
(TagFact a -> TagFact b -> TagFact (Multiply a b))
-> MultiplyTagLaw b a
MultiplyTagLaw TagFact Big -> TagFact b -> TagFact (Multiply Big b)
forall a b. a -> b -> a
const)

heightFact :: (C vert) => Extent meas vert horiz height width -> TagFact vert
heightFact :: Extent meas vert horiz height width -> TagFact vert
heightFact Extent meas vert horiz height width
_ = TagFact vert
forall a. C a => TagFact a
TagFact

widthFact :: (C horiz) => Extent meas vert horiz height width -> TagFact horiz
widthFact :: Extent meas vert horiz height width -> TagFact horiz
widthFact Extent meas vert horiz height width
_ = TagFact horiz
forall a. C a => TagFact a
TagFact


data MeasureFact a = Measure a => MeasureFact

newtype MultiplyMeasureLaw b a =
   MultiplyMeasureLaw {
      MultiplyMeasureLaw b a
-> MeasureFact a
-> MeasureFact b
-> MeasureFact (MultiplyMeasure a b)
getMultiplyMeasureLaw ::
         MeasureFact a -> MeasureFact b -> MeasureFact (MultiplyMeasure a b)
   }

multiplyMeasureLaw ::
   MeasureFact a -> MeasureFact b -> MeasureFact (MultiplyMeasure a b)
multiplyMeasureLaw :: MeasureFact a -> MeasureFact b -> MeasureFact (MultiplyMeasure a b)
multiplyMeasureLaw a :: MeasureFact a
a@MeasureFact a
MeasureFact =
   ((MeasureFact a
 -> MeasureFact b -> MeasureFact (MultiplyMeasure a b))
-> MeasureFact a
-> MeasureFact b
-> MeasureFact (MultiplyMeasure a b)
forall a b. (a -> b) -> a -> b
$MeasureFact a
a) ((MeasureFact a
  -> MeasureFact b -> MeasureFact (MultiplyMeasure a b))
 -> MeasureFact b -> MeasureFact (MultiplyMeasure a b))
-> (MeasureFact a
    -> MeasureFact b -> MeasureFact (MultiplyMeasure a b))
-> MeasureFact b
-> MeasureFact (MultiplyMeasure a b)
forall a b. (a -> b) -> a -> b
$ MultiplyMeasureLaw b a
-> MeasureFact a
-> MeasureFact b
-> MeasureFact (MultiplyMeasure a b)
forall b a.
MultiplyMeasureLaw b a
-> MeasureFact a
-> MeasureFact b
-> MeasureFact (MultiplyMeasure a b)
getMultiplyMeasureLaw (MultiplyMeasureLaw b a
 -> MeasureFact a
 -> MeasureFact b
 -> MeasureFact (MultiplyMeasure a b))
-> MultiplyMeasureLaw b a
-> MeasureFact a
-> MeasureFact b
-> MeasureFact (MultiplyMeasure a b)
forall a b. (a -> b) -> a -> b
$
   MultiplyMeasureLaw b Shape
-> MultiplyMeasureLaw b Size -> MultiplyMeasureLaw b a
forall meas (f :: * -> *).
Measure meas =>
f Shape -> f Size -> f meas
switchMeasure
      ((MeasureFact Shape
 -> MeasureFact b -> MeasureFact (MultiplyMeasure Shape b))
-> MultiplyMeasureLaw b Shape
forall b a.
(MeasureFact a
 -> MeasureFact b -> MeasureFact (MultiplyMeasure a b))
-> MultiplyMeasureLaw b a
MultiplyMeasureLaw ((MeasureFact Shape
  -> MeasureFact b -> MeasureFact (MultiplyMeasure Shape b))
 -> MultiplyMeasureLaw b Shape)
-> (MeasureFact Shape
    -> MeasureFact b -> MeasureFact (MultiplyMeasure Shape b))
-> MultiplyMeasureLaw b Shape
forall a b. (a -> b) -> a -> b
$ (MeasureFact b -> MeasureFact Shape -> MeasureFact b)
-> MeasureFact Shape -> MeasureFact b -> MeasureFact b
forall a b c. (a -> b -> c) -> b -> a -> c
flip MeasureFact b -> MeasureFact Shape -> MeasureFact b
forall a b. a -> b -> a
const)
      ((MeasureFact Size
 -> MeasureFact b -> MeasureFact (MultiplyMeasure Size b))
-> MultiplyMeasureLaw b Size
forall b a.
(MeasureFact a
 -> MeasureFact b -> MeasureFact (MultiplyMeasure a b))
-> MultiplyMeasureLaw b a
MultiplyMeasureLaw MeasureFact Size
-> MeasureFact b -> MeasureFact (MultiplyMeasure Size b)
forall a b. a -> b -> a
const)

measureFact ::
   (Measure meas) => Extent meas vert horiz height width -> MeasureFact meas
measureFact :: Extent meas vert horiz height width -> MeasureFact meas
measureFact Extent meas vert horiz height width
_ = MeasureFact meas
forall a. Measure a => MeasureFact a
MeasureFact


newtype
   Unify height fuse width heightC widthC
      measB vertB horizB measA vertA horizA =
   Unify {
      Unify
  height
  fuse
  width
  heightC
  widthC
  measB
  vertB
  horizB
  measA
  vertA
  horizA
-> Extent measA vertA horizA height fuse
-> Extent measB vertB horizB fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply vertA vertB)
     (Multiply horizA horizB)
     heightC
     widthC
getUnify ::
         Extent measA vertA horizA height fuse ->
         Extent measB vertB horizB fuse width ->
         Extent (MultiplyMeasure measA measB)
            (Multiply vertA vertB) (Multiply horizA horizB) heightC widthC
   }

unifyLeft ::
   (Measure measA, Measure measB, C vertA, C horizA, C vertB, C horizB) =>
   Extent measA vertA horizA height fuse ->
   Extent measB vertB horizB fuse width ->
   Extent (MultiplyMeasure measA measB)
      (Multiply vertA vertB) (Multiply horizA horizB) height fuse
unifyLeft :: Extent measA vertA horizA height fuse
-> Extent measB vertB horizB fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply vertA vertB)
     (Multiply horizA horizB)
     height
     fuse
unifyLeft =
   Unify
  height fuse width height fuse measB vertB horizB measA vertA horizA
-> Extent measA vertA horizA height fuse
-> Extent measB vertB horizB fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply vertA vertB)
     (Multiply horizA horizB)
     height
     fuse
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
Unify
  height
  fuse
  width
  heightC
  widthC
  measB
  vertB
  horizB
  measA
  vertA
  horizA
-> Extent measA vertA horizA height fuse
-> Extent measB vertB horizB fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply vertA vertB)
     (Multiply horizA horizB)
     heightC
     widthC
getUnify (Unify
   height fuse width height fuse measB vertB horizB measA vertA horizA
 -> Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      height
      fuse)
-> Unify
     height fuse width height fuse measB vertB horizB measA vertA horizA
-> Extent measA vertA horizA height fuse
-> Extent measB vertB horizB fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply vertA vertB)
     (Multiply horizA horizB)
     height
     fuse
forall a b. (a -> b) -> a -> b
$
   Unify
  height fuse width height fuse measB vertB horizB Shape Small Small
-> Unify
     height fuse width height fuse measB vertB horizB Size Small Small
-> Unify
     height fuse width height fuse measB vertB horizB Size Small Big
-> Unify
     height fuse width height fuse measB vertB horizB Size Big Small
-> Unify
     height fuse width height fuse measB vertB horizB Size Big Big
-> Unify
     height fuse width height fuse measB vertB horizB measA vertA horizA
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f Shape Small Small
-> f Size Small Small
-> f Size Small Big
-> f Size Big Small
-> f Size Big Big
-> f meas vert horiz
switchTagTriple
      ((Extent Shape Small Small height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure Shape measB)
      (Multiply Small vertB)
      (Multiply Small horizB)
      height
      fuse)
-> Unify
     height fuse width height fuse measB vertB horizB Shape Small Small
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
(Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      heightC
      widthC)
-> Unify
     height
     fuse
     width
     heightC
     widthC
     measB
     vertB
     horizB
     measA
     vertA
     horizA
Unify ((Extent Shape Small Small height fuse
  -> Extent measB vertB horizB fuse width
  -> Extent
       (MultiplyMeasure Shape measB)
       (Multiply Small vertB)
       (Multiply Small horizB)
       height
       fuse)
 -> Unify
      height fuse width height fuse measB vertB horizB Shape Small Small)
-> (Extent Shape Small Small height fuse
    -> Extent measB vertB horizB fuse width
    -> Extent
         (MultiplyMeasure Shape measB)
         (Multiply Small vertB)
         (Multiply Small horizB)
         height
         fuse)
-> Unify
     height fuse width height fuse measB vertB horizB Shape Small Small
forall a b. (a -> b) -> a -> b
$ Extent measB vertB horizB height fuse
-> Extent measB vertB horizB fuse width
-> Extent measB vertB horizB height fuse
forall a b. a -> b -> a
const (Extent measB vertB horizB height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent measB vertB horizB height fuse)
-> (Extent Shape Small Small height fuse
    -> Extent measB vertB horizB height fuse)
-> Extent Shape Small Small height fuse
-> Extent measB vertB horizB fuse width
-> Extent measB vertB horizB height fuse
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Extent Shape Small Small height fuse
-> Extent measB vertB horizB height fuse
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent Shape Small Small height width
-> Extent meas vert horiz height width
fromSquareLiberal)
      ((Extent Size Small Small height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure Size measB)
      (Multiply Small vertB)
      (Multiply Small horizB)
      height
      fuse)
-> Unify
     height fuse width height fuse measB vertB horizB Size Small Small
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
(Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      heightC
      widthC)
-> Unify
     height
     fuse
     width
     heightC
     widthC
     measB
     vertB
     horizB
     measA
     vertA
     horizA
Unify ((Extent Size Small Small height fuse
  -> Extent measB vertB horizB fuse width
  -> Extent
       (MultiplyMeasure Size measB)
       (Multiply Small vertB)
       (Multiply Small horizB)
       height
       fuse)
 -> Unify
      height fuse width height fuse measB vertB horizB Size Small Small)
-> (Extent Size Small Small height fuse
    -> Extent measB vertB horizB fuse width
    -> Extent
         (MultiplyMeasure Size measB)
         (Multiply Small vertB)
         (Multiply Small horizB)
         height
         fuse)
-> Unify
     height fuse width height fuse measB vertB horizB Size Small Small
forall a b. (a -> b) -> a -> b
$ Extent Size vertB horizB height fuse
-> Extent measB vertB horizB fuse width
-> Extent Size vertB horizB height fuse
forall a b. a -> b -> a
const (Extent Size vertB horizB height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent Size vertB horizB height fuse)
-> (Extent Size Small Small height fuse
    -> Extent Size vertB horizB height fuse)
-> Extent Size Small Small height fuse
-> Extent measB vertB horizB fuse width
-> Extent Size vertB horizB height fuse
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Extent Size Small Small height fuse
-> Extent Size vertB horizB height fuse
forall vert horiz height width.
(C vert, C horiz) =>
LiberalSquare height width -> Extent Size vert horiz height width
fromLiberalSquare)
      ((Extent Size Small Big height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure Size measB)
      (Multiply Small vertB)
      (Multiply Big horizB)
      height
      fuse)
-> Unify
     height fuse width height fuse measB vertB horizB Size Small Big
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
(Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      heightC
      widthC)
-> Unify
     height
     fuse
     width
     heightC
     widthC
     measB
     vertB
     horizB
     measA
     vertA
     horizA
Unify ((Extent Size Small Big height fuse
  -> Extent measB vertB horizB fuse width
  -> Extent
       (MultiplyMeasure Size measB)
       (Multiply Small vertB)
       (Multiply Big horizB)
       height
       fuse)
 -> Unify
      height fuse width height fuse measB vertB horizB Size Small Big)
-> (Extent Size Small Big height fuse
    -> Extent measB vertB horizB fuse width
    -> Extent
         (MultiplyMeasure Size measB)
         (Multiply Small vertB)
         (Multiply Big horizB)
         height
         fuse)
-> Unify
     height fuse width height fuse measB vertB horizB Size Small Big
forall a b. (a -> b) -> a -> b
$ Extent Size vertB Big height fuse
-> Extent measB vertB horizB fuse width
-> Extent Size vertB Big height fuse
forall a b. a -> b -> a
const (Extent Size vertB Big height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent Size vertB Big height fuse)
-> (Extent Size Small Big height fuse
    -> Extent Size vertB Big height fuse)
-> Extent Size Small Big height fuse
-> Extent measB vertB horizB fuse width
-> Extent Size vertB Big height fuse
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Extent Size Small Big height fuse
-> Extent Size vertB Big height fuse
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas Small horiz height width
-> Extent Size vert horiz height width
generalizeWide)
      ((Extent Size Big Small height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure Size measB)
      (Multiply Big vertB)
      (Multiply Small horizB)
      height
      fuse)
-> Unify
     height fuse width height fuse measB vertB horizB Size Big Small
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
(Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      heightC
      widthC)
-> Unify
     height
     fuse
     width
     heightC
     widthC
     measB
     vertB
     horizB
     measA
     vertA
     horizA
Unify ((Extent Size Big Small height fuse
  -> Extent measB vertB horizB fuse width
  -> Extent
       (MultiplyMeasure Size measB)
       (Multiply Big vertB)
       (Multiply Small horizB)
       height
       fuse)
 -> Unify
      height fuse width height fuse measB vertB horizB Size Big Small)
-> (Extent Size Big Small height fuse
    -> Extent measB vertB horizB fuse width
    -> Extent
         (MultiplyMeasure Size measB)
         (Multiply Big vertB)
         (Multiply Small horizB)
         height
         fuse)
-> Unify
     height fuse width height fuse measB vertB horizB Size Big Small
forall a b. (a -> b) -> a -> b
$ Extent Size Big horizB height fuse
-> Extent measB vertB horizB fuse width
-> Extent Size Big horizB height fuse
forall a b. a -> b -> a
const (Extent Size Big horizB height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent Size Big horizB height fuse)
-> (Extent Size Big Small height fuse
    -> Extent Size Big horizB height fuse)
-> Extent Size Big Small height fuse
-> Extent measB vertB horizB fuse width
-> Extent Size Big horizB height fuse
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Extent Size Big Small height fuse
-> Extent Size Big horizB height fuse
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert Small height width
-> Extent Size vert horiz height width
generalizeTall)
      ((Extent Size Big Big height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure Size measB)
      (Multiply Big vertB)
      (Multiply Big horizB)
      height
      fuse)
-> Unify
     height fuse width height fuse measB vertB horizB Size Big Big
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
(Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      heightC
      widthC)
-> Unify
     height
     fuse
     width
     heightC
     widthC
     measB
     vertB
     horizB
     measA
     vertA
     horizA
Unify ((Extent Size Big Big height fuse
  -> Extent measB vertB horizB fuse width
  -> Extent
       (MultiplyMeasure Size measB)
       (Multiply Big vertB)
       (Multiply Big horizB)
       height
       fuse)
 -> Unify
      height fuse width height fuse measB vertB horizB Size Big Big)
-> (Extent Size Big Big height fuse
    -> Extent measB vertB horizB fuse width
    -> Extent
         (MultiplyMeasure Size measB)
         (Multiply Big vertB)
         (Multiply Big horizB)
         height
         fuse)
-> Unify
     height fuse width height fuse measB vertB horizB Size Big Big
forall a b. (a -> b) -> a -> b
$ Extent Size Big Big height fuse
-> Extent measB vertB horizB fuse width
-> Extent Size Big Big height fuse
forall a b. a -> b -> a
const (Extent Size Big Big height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent Size Big Big height fuse)
-> (Extent Size Big Big height fuse
    -> Extent Size Big Big height fuse)
-> Extent Size Big Big height fuse
-> Extent measB vertB horizB fuse width
-> Extent Size Big Big height fuse
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Extent Size Big Big height fuse -> Extent Size Big Big height fuse
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> General height width
toGeneral)

unifyRight ::
   (Measure measA, Measure measB, C vertA, C horizA, C vertB, C horizB) =>
   Extent measA vertA horizA height fuse ->
   Extent measB vertB horizB fuse width ->
   Extent (MultiplyMeasure measA measB)
      (Multiply vertA vertB) (Multiply horizA horizB) fuse width
unifyRight :: Extent measA vertA horizA height fuse
-> Extent measB vertB horizB fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply vertA vertB)
     (Multiply horizA horizB)
     fuse
     width
unifyRight =
   Unify
  height fuse width fuse width measB vertB horizB measA vertA horizA
-> Extent measA vertA horizA height fuse
-> Extent measB vertB horizB fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply vertA vertB)
     (Multiply horizA horizB)
     fuse
     width
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
Unify
  height
  fuse
  width
  heightC
  widthC
  measB
  vertB
  horizB
  measA
  vertA
  horizA
-> Extent measA vertA horizA height fuse
-> Extent measB vertB horizB fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply vertA vertB)
     (Multiply horizA horizB)
     heightC
     widthC
getUnify (Unify
   height fuse width fuse width measB vertB horizB measA vertA horizA
 -> Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      fuse
      width)
-> Unify
     height fuse width fuse width measB vertB horizB measA vertA horizA
-> Extent measA vertA horizA height fuse
-> Extent measB vertB horizB fuse width
-> Extent
     (MultiplyMeasure measA measB)
     (Multiply vertA vertB)
     (Multiply horizA horizB)
     fuse
     width
forall a b. (a -> b) -> a -> b
$
   Unify
  height fuse width fuse width measB vertB horizB Shape Small Small
-> Unify
     height fuse width fuse width measB vertB horizB Size Small Small
-> Unify
     height fuse width fuse width measB vertB horizB Size Small Big
-> Unify
     height fuse width fuse width measB vertB horizB Size Big Small
-> Unify
     height fuse width fuse width measB vertB horizB Size Big Big
-> Unify
     height fuse width fuse width measB vertB horizB measA vertA horizA
forall meas vert horiz (f :: * -> * -> * -> *).
(Measure meas, C vert, C horiz) =>
f Shape Small Small
-> f Size Small Small
-> f Size Small Big
-> f Size Big Small
-> f Size Big Big
-> f meas vert horiz
switchTagTriple
      ((Extent Shape Small Small height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure Shape measB)
      (Multiply Small vertB)
      (Multiply Small horizB)
      fuse
      width)
-> Unify
     height fuse width fuse width measB vertB horizB Shape Small Small
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
(Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      heightC
      widthC)
-> Unify
     height
     fuse
     width
     heightC
     widthC
     measB
     vertB
     horizB
     measA
     vertA
     horizA
Unify ((Extent Shape Small Small height fuse
  -> Extent measB vertB horizB fuse width
  -> Extent
       (MultiplyMeasure Shape measB)
       (Multiply Small vertB)
       (Multiply Small horizB)
       fuse
       width)
 -> Unify
      height fuse width fuse width measB vertB horizB Shape Small Small)
-> (Extent Shape Small Small height fuse
    -> Extent measB vertB horizB fuse width
    -> Extent
         (MultiplyMeasure Shape measB)
         (Multiply Small vertB)
         (Multiply Small horizB)
         fuse
         width)
-> Unify
     height fuse width fuse width measB vertB horizB Shape Small Small
forall a b. (a -> b) -> a -> b
$ (Extent measB vertB horizB fuse width
 -> Extent measB vertB horizB fuse width)
-> Extent Shape Small Small height fuse
-> Extent measB vertB horizB fuse width
-> Extent measB vertB horizB fuse width
forall a b. a -> b -> a
const Extent measB vertB horizB fuse width
-> Extent measB vertB horizB fuse width
forall a. a -> a
id)
      ((Extent Size Small Small height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure Size measB)
      (Multiply Small vertB)
      (Multiply Small horizB)
      fuse
      width)
-> Unify
     height fuse width fuse width measB vertB horizB Size Small Small
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
(Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      heightC
      widthC)
-> Unify
     height
     fuse
     width
     heightC
     widthC
     measB
     vertB
     horizB
     measA
     vertA
     horizA
Unify ((Extent Size Small Small height fuse
  -> Extent measB vertB horizB fuse width
  -> Extent
       (MultiplyMeasure Size measB)
       (Multiply Small vertB)
       (Multiply Small horizB)
       fuse
       width)
 -> Unify
      height fuse width fuse width measB vertB horizB Size Small Small)
-> (Extent Size Small Small height fuse
    -> Extent measB vertB horizB fuse width
    -> Extent
         (MultiplyMeasure Size measB)
         (Multiply Small vertB)
         (Multiply Small horizB)
         fuse
         width)
-> Unify
     height fuse width fuse width measB vertB horizB Size Small Small
forall a b. (a -> b) -> a -> b
$ (Extent measB vertB horizB fuse width
 -> Extent Size vertB horizB fuse width)
-> Extent Size Small Small height fuse
-> Extent measB vertB horizB fuse width
-> Extent Size vertB horizB fuse width
forall a b. a -> b -> a
const Extent measB vertB horizB fuse width
-> Extent Size vertB horizB fuse width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width
-> Extent Size vert horiz height width
relaxMeasure)
      ((Extent Size Small Big height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure Size measB)
      (Multiply Small vertB)
      (Multiply Big horizB)
      fuse
      width)
-> Unify
     height fuse width fuse width measB vertB horizB Size Small Big
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
(Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      heightC
      widthC)
-> Unify
     height
     fuse
     width
     heightC
     widthC
     measB
     vertB
     horizB
     measA
     vertA
     horizA
Unify ((Extent Size Small Big height fuse
  -> Extent measB vertB horizB fuse width
  -> Extent
       (MultiplyMeasure Size measB)
       (Multiply Small vertB)
       (Multiply Big horizB)
       fuse
       width)
 -> Unify
      height fuse width fuse width measB vertB horizB Size Small Big)
-> (Extent Size Small Big height fuse
    -> Extent measB vertB horizB fuse width
    -> Extent
         (MultiplyMeasure Size measB)
         (Multiply Small vertB)
         (Multiply Big horizB)
         fuse
         width)
-> Unify
     height fuse width fuse width measB vertB horizB Size Small Big
forall a b. (a -> b) -> a -> b
$ (Extent measB vertB horizB fuse width
 -> Extent Size vertB Big fuse width)
-> Extent Size Small Big height fuse
-> Extent measB vertB horizB fuse width
-> Extent Size vertB Big fuse width
forall a b. a -> b -> a
const Extent measB vertB horizB fuse width
-> Extent Size vertB Big fuse width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width
-> Extent Size vert Big height width
genToWide)
      ((Extent Size Big Small height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure Size measB)
      (Multiply Big vertB)
      (Multiply Small horizB)
      fuse
      width)
-> Unify
     height fuse width fuse width measB vertB horizB Size Big Small
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
(Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      heightC
      widthC)
-> Unify
     height
     fuse
     width
     heightC
     widthC
     measB
     vertB
     horizB
     measA
     vertA
     horizA
Unify ((Extent Size Big Small height fuse
  -> Extent measB vertB horizB fuse width
  -> Extent
       (MultiplyMeasure Size measB)
       (Multiply Big vertB)
       (Multiply Small horizB)
       fuse
       width)
 -> Unify
      height fuse width fuse width measB vertB horizB Size Big Small)
-> (Extent Size Big Small height fuse
    -> Extent measB vertB horizB fuse width
    -> Extent
         (MultiplyMeasure Size measB)
         (Multiply Big vertB)
         (Multiply Small horizB)
         fuse
         width)
-> Unify
     height fuse width fuse width measB vertB horizB Size Big Small
forall a b. (a -> b) -> a -> b
$ (Extent measB vertB horizB fuse width
 -> Extent Size Big horizB fuse width)
-> Extent Size Big Small height fuse
-> Extent measB vertB horizB fuse width
-> Extent Size Big horizB fuse width
forall a b. a -> b -> a
const Extent measB vertB horizB fuse width
-> Extent Size Big horizB fuse width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width
-> Extent Size Big horiz height width
genToTall)
      ((Extent Size Big Big height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure Size measB)
      (Multiply Big vertB)
      (Multiply Big horizB)
      fuse
      width)
-> Unify
     height fuse width fuse width measB vertB horizB Size Big Big
forall height fuse width heightC widthC measB vertB horizB measA
       vertA horizA.
(Extent measA vertA horizA height fuse
 -> Extent measB vertB horizB fuse width
 -> Extent
      (MultiplyMeasure measA measB)
      (Multiply vertA vertB)
      (Multiply horizA horizB)
      heightC
      widthC)
-> Unify
     height
     fuse
     width
     heightC
     widthC
     measB
     vertB
     horizB
     measA
     vertA
     horizA
Unify ((Extent Size Big Big height fuse
  -> Extent measB vertB horizB fuse width
  -> Extent
       (MultiplyMeasure Size measB)
       (Multiply Big vertB)
       (Multiply Big horizB)
       fuse
       width)
 -> Unify
      height fuse width fuse width measB vertB horizB Size Big Big)
-> (Extent Size Big Big height fuse
    -> Extent measB vertB horizB fuse width
    -> Extent
         (MultiplyMeasure Size measB)
         (Multiply Big vertB)
         (Multiply Big horizB)
         fuse
         width)
-> Unify
     height fuse width fuse width measB vertB horizB Size Big Big
forall a b. (a -> b) -> a -> b
$ (Extent measB vertB horizB fuse width -> General fuse width)
-> Extent Size Big Big height fuse
-> Extent measB vertB horizB fuse width
-> General fuse width
forall a b. a -> b -> a
const Extent measB vertB horizB fuse width -> General fuse width
forall meas vert horiz height width.
(Measure meas, C vert, C horiz) =>
Extent meas vert horiz height width -> General height width
toGeneral)


{-
Square  Square  -> Square
Square  Wide    -> Wide
Square  Tall    -> Tall
Square  General -> General
Wide    Square  -> Wide
Wide    Wide    -> Wide
Wide    Tall    -> General
Wide    General -> General
Tall    Square  -> Tall
Tall    Wide    -> General
Tall    Tall    -> Tall
Tall    General -> General
General Square  -> General
General Wide    -> General
General Tall    -> General
General General -> General

Small Small  Small Small -> Small Small
Small Small  Small Big   -> Small Big
Small Small  Big   Small -> Big   Small
Small Small  Big   Big   -> Big   Big
Small Big    Small Small -> Small Big
Small Big    Small Big   -> Small Big
Small Big    Big   Small -> Big   Big
Small Big    Big   Big   -> Big   Big
Big   Small  Small Small -> Big   Small
Big   Small  Small Big   -> Big   Big
Big   Small  Big   Small -> Big   Small
Big   Small  Big   Big   -> Big   Big
Big   Big    Small Small -> Big   Big
Big   Big    Small Big   -> Big   Big
Big   Big    Big   Small -> Big   Big
Big   Big    Big   Big   -> Big   Big
-}