{-# LANGUAGE TypeFamilies #-} {-# OPTIONS -Wall #-} -------------------------------------------------------------------------------- -- | -- Module : Wumpus.Basic.Kernel.Objects.Concat -- Copyright : (c) Stephen Tetley 2011 -- License : BSD3 -- -- Maintainer : stephen.tetley@gmail.com -- Stability : highly unstable -- Portability : GHC -- -- Classes for concatenation. -- -------------------------------------------------------------------------------- module Wumpus.Basic.Kernel.Objects.Concat ( ZConcat(..) , cat , Concat(..) , hcat , vcat , CatSpace(..) , hsep , vsep , Align(..) , alignRow , alignColumn , AlignSpace(..) , alignRowSep , alignColumnSep ) where import Wumpus.Basic.Kernel.Base.BaseDefs import Wumpus.Core -- package: wumpus-core import Data.Monoid infixr 6 `superior`, `anterior` -- | Minimal defintion is 'superior', 'anterior' is usually -- @flip superior@. -- -- > `superior` (infixr 6) -- -- > `anterior` (infixr 6) -- -- class ZConcat o where anterior :: o -> o -> o superior :: o -> o -> o anterior = flip superior cat :: (Monoid o, ZConcat o) => [o] -> o cat [] = mempty cat (x:xs) = go x xs where go acc [] = acc go acc (a:as) = go (acc `superior` a) as infixr 6 `hconcat` infixr 5 `vconcat` -- | Concatenation with /movement/ - the second object is moved -- next to the first. -- -- > hconcat is equivalent to @(<>)@ in WL-PPrint. -- > (infixr 6) -- -- > vconcat is equivalent to @(<$>)@ in WL_PPrint. -- > (infixr 5) -- class Concat o where hconcat :: o -> o -> o vconcat :: o -> o -> o -- | Horizontally concatenate a list of objects. -- -- Note - the first argument is an /alternative/ - this is drawn -- if the list is empty, otherwise it is not drawn. -- hcat :: (Monoid o, Concat o) => [o] -> o hcat [] = mempty hcat (x:xs) = go x xs where go acc [] = acc go acc (a:as) = go (acc `hconcat` a) as -- | Vertically concatenate a list of objects. -- -- Note - the first argument is an /alternative/ - this is drawn -- if the list is empty, otherwise it is not drawn. -- vcat :: (Monoid o, Concat o) => [o] -> o vcat [] = mempty vcat (x:xs) = go x xs where go acc [] = acc go acc (a:as) = go (acc `vconcat` a) as class CatSpace o where hspace :: u ~ DUnit o => u -> o -> o -> o vspace :: u ~ DUnit o => u -> o -> o -> o hsep :: (Monoid o, CatSpace o, u ~ DUnit o) => u -> [o] -> o hsep _ [] = mempty hsep dx (x:xs) = go x xs where op = hspace dx go acc [] = acc go acc (a:as) = go (acc `op` a) as vsep :: (Monoid o, CatSpace o, u ~ DUnit o) => u -> [o] -> o vsep _ [] = mempty vsep dx (x:xs) = go x xs where op = vspace dx go acc [] = acc go acc (a:as) = go (acc `op` a) as class Align o where halign :: HAlign -> o -> o -> o valign :: VAlign -> o -> o -> o alignRow :: (Monoid o, Align o) => HAlign -> [o] -> o alignRow _ [] = mempty alignRow ha (x:xs) = go x xs where op = halign ha go acc [] = acc go acc (a:as) = go (acc `op` a) as alignColumn :: (Monoid o, Align o) => VAlign -> [o] -> o alignColumn _ [] = mempty alignColumn va (x:xs) = go x xs where op = valign va go acc [] = acc go acc (a:as) = go (acc `op` a) as class AlignSpace o where halignSpace :: u ~ DUnit o => HAlign -> u -> o -> o -> o valignSpace :: u ~ DUnit o => VAlign -> u -> o -> o -> o alignRowSep :: (Monoid o, AlignSpace o, u ~ DUnit o) => HAlign -> u -> [o] -> o alignRowSep _ _ [] = mempty alignRowSep ha dx (x:xs) = go x xs where op = halignSpace ha dx go acc [] = acc go acc (a:as) = go (acc `op` a) as alignColumnSep :: (Monoid o, AlignSpace o, u ~ DUnit o) => VAlign -> u -> [o] -> o alignColumnSep _ _ [] = mempty alignColumnSep va dx (x:xs) = go x xs where op = valignSpace va dx go acc [] = acc go acc (a:as) = go (acc `op` a) as