{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Diagrams.Core.Juxtapose
( Juxtaposable(..), juxtaposeDefault
) where
import Control.Applicative
import qualified Data.Map as M
import qualified Data.Set as S
import Diagrams.Core.Envelope
import Diagrams.Core.Measure
import Diagrams.Core.HasOrigin
import Diagrams.Core.V
import Linear.Metric
import Linear.Vector
class Juxtaposable a where
juxtapose :: Vn a -> a -> a -> a
juxtaposeDefault :: (Enveloped a, HasOrigin a) => Vn a -> a -> a -> a
juxtaposeDefault v a1 a2 =
case (mv1, mv2) of
(Just v1, Just v2) -> moveOriginBy (v1 ^+^ v2) a2
_ -> a2
where mv1 = negated <$> envelopeVMay v a1
mv2 = envelopeVMay (negated v) a2
instance (Metric v, OrderedField n) => Juxtaposable (Envelope v n) where
juxtapose = juxtaposeDefault
instance (Enveloped a, HasOrigin a, Enveloped b, HasOrigin b, V a ~ V b, N a ~ N b)
=> Juxtaposable (a,b) where
juxtapose = juxtaposeDefault
instance (Enveloped b, HasOrigin b) => Juxtaposable [b] where
juxtapose = juxtaposeDefault
instance (Enveloped b, HasOrigin b) => Juxtaposable (M.Map k b) where
juxtapose = juxtaposeDefault
instance (Enveloped b, HasOrigin b, Ord b) => Juxtaposable (S.Set b) where
juxtapose = juxtaposeDefault
instance Juxtaposable a => Juxtaposable (b -> a) where
juxtapose v f1 f2 b = juxtapose v (f1 b) (f2 b)
instance Juxtaposable a => Juxtaposable (Measured n a) where
juxtapose v = liftA2 (juxtapose v)