wumpus-basic-0.9.0: src/Wumpus/Basic/Graphic/BaseClasses.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# OPTIONS -Wall #-}
--------------------------------------------------------------------------------
-- |
-- Module : Wumpus.Basic.Graphic.BaseClasses
-- Copyright : (c) Stephen Tetley 2010
-- License : BSD3
--
-- Maintainer : stephen.tetley@gmail.com
-- Stability : unstable
-- Portability : GHC
--
-- Base classes and type families.
--
-- Drawing is always built on TraceM and DrawingCtxM, it may use
-- PointSupplyM for chains or turtle drawing.
--
--------------------------------------------------------------------------------
module Wumpus.Basic.Graphic.BaseClasses
(
MonUnit
, TraceM(..)
, DrawingCtxM(..)
, asksCtx
, ScalingM(..)
, PointSupplyM(..)
) where
import Wumpus.Basic.Graphic.BaseTypes ( HPrim )
import Wumpus.Basic.Graphic.DrawingContext
import Wumpus.Core -- package: wumpus-core
-- DUnit is always for fully saturated type constructors, so
-- (seemingly) an equivalent type family is needed for monads.
type family MonUnit m :: *
-- | Collect elementary graphics as part of a larger drawing.
--
-- TraceM works much like a writer monad.
--
class Monad m => TraceM (m :: * -> *) where
trace :: HPrim (MonUnit m) -> m ()
class Monad m => DrawingCtxM (m :: * -> *) where
askCtx :: m DrawingContext
localCtx :: (DrawingContext -> DrawingContext) -> m a -> m a
-- | Project a value out of a context.
--
asksCtx :: DrawingCtxM m => (DrawingContext -> a) -> m a
asksCtx f = askCtx >>= (return . f)
-- | Scaling...
--
class ScalingM m where
type XDim m :: *
type YDim m :: *
scaleX :: (u ~ MonUnit m, ux ~ XDim m) => ux -> m u
scaleY :: (u ~ MonUnit m, uy ~ YDim m) => uy -> m u
scalePt :: (u ~ MonUnit m, ux ~ XDim m, uy ~ YDim m)
=> ux -> uy -> m (Point2 u)
scaleVec :: (u ~ MonUnit m, ux ~ XDim m, uy ~ YDim m)
=> ux -> uy -> m (Vec2 u)
-- | A monad that supplies points, e.g. a turtle monad.
--
class Monad m => PointSupplyM (m :: * -> *) where
position :: u ~ MonUnit m => m (Point2 u)