never executed always true always false
    1 module HelVM.HelMA.Automata.Piet.Types.Label
    2   ( LabelBorder (..)
    3   , LabelInfo (..)
    4   , LabelKey
    5   , addPixel
    6   , borderCoord
    7   , borderMax
    8   , borderMin
    9   , getLabelSize
   10   , labelBottom
   11   , labelLeft
   12   , labelRight
   13   , labelSize
   14   , labelTop
   15   ) where
   16 
   17 import           HelVM.HelMA.Automata.Piet.Types.Coordinates
   18 
   19 import           Lens.Micro                                  ( (%~), (^.) )
   20 import           Lens.Micro.TH                               ( makeLenses )
   21 
   22 -- Types
   23 
   24 type LabelKey = Int
   25 
   26 data LabelBorder
   27   = LabelBorder
   28       { _borderCoord :: !Int
   29       , _borderMin   :: !Int
   30       , _borderMax   :: !Int
   31       }
   32   deriving stock (Eq, Ord, Show)
   33 
   34 makeLenses ''LabelBorder
   35 
   36 data LabelInfo
   37   = LabelInfo
   38       { _labelSize   :: !Int
   39       , _labelTop    :: !LabelBorder
   40       , _labelLeft   :: !LabelBorder
   41       , _labelBottom :: !LabelBorder
   42       , _labelRight  :: !LabelBorder
   43       }
   44   deriving stock (Eq, Ord, Show)
   45 
   46 makeLenses ''LabelInfo
   47 
   48 -- Exported Functions
   49 
   50 addPixel ∷ Coordinates → Maybe LabelInfo → Maybe LabelInfo
   51 addPixel (x, y) Nothing = Just $ LabelInfo 1 (LabelBorder y x x) (LabelBorder x y y) (LabelBorder y x x) (LabelBorder x y y)
   52 addPixel (x, y) (Just stats) = Just $ stats
   53   & labelSize %~ (+ 1)
   54   & labelTop %~ (`mergeMin` LabelBorder y x x)
   55   & labelLeft %~ (`mergeMin` LabelBorder x y y)
   56   & labelBottom %~ (`mergeMax` LabelBorder y x x)
   57   & labelRight %~ (`mergeMax` LabelBorder x y y)
   58 
   59 getLabelSize ∷ Maybe LabelInfo → Int
   60 getLabelSize Nothing     = 0
   61 getLabelSize (Just info) = info ^. labelSize
   62 
   63 instance Semigroup LabelInfo where
   64   s1 <> s2 = LabelInfo
   65     (s1 ^. labelSize + s2 ^. labelSize)
   66     (mergeMin (s1 ^. labelTop) (s2 ^. labelTop))
   67     (mergeMin (s1 ^. labelLeft) (s2 ^. labelLeft))
   68     (mergeMax (s1 ^. labelBottom) (s2 ^. labelBottom))
   69     (mergeMax (s1 ^. labelRight) (s2 ^. labelRight))
   70 
   71 -- Internal
   72 
   73 mergeMin ∷ LabelBorder → LabelBorder → LabelBorder
   74 mergeMin = merge $ comparing (^. borderCoord)
   75 
   76 mergeMax ∷ LabelBorder → LabelBorder → LabelBorder
   77 mergeMax = merge $ comparing (negate . (^. borderCoord))
   78 
   79 merge ∷ (LabelBorder → LabelBorder → Ordering) → LabelBorder → LabelBorder → LabelBorder
   80 merge comp b1 b2 = go $ comp b1 b2 where
   81   go EQ = b1
   82     & borderMin %~ min (b2 ^. borderMin)
   83     & borderMax %~ max (b2 ^. borderMax)
   84   go LT = b1
   85   go GT = b2