{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} -------------------------------------------------------------------- -- | -- Copyright : (c) Jann Müller 2018 -- License : MIT -- Maintainer: Jann Müller <j.mueller.11@alumni.ucl.ac.uk> -- Stability : experimental -- Portability: non-portable -- -- Type classes for scales. A scale is a family of functions that are -- parameterised by a target range (for example, the dimensions of the -- diagram in pixels) and an additional set of options specific to each -- scale. -- -- In @h3@, 'Scalable' is the type class that represents scales. -- Scales used for visualisation commonly have metadata such as legends, grid -- lines etc. The 'Data.H3.Visuals.ChartVisuals' class deals with this kind of -- data. -------------------------------------------------------------------- module Data.H3.Scalable( -- * Scales Scalable(..), -- * Basic instances arrow ) where import Data.Functor.Identity (Identity (..)) -- | The class of scales. Each scale has an associated data type 'ScaleOptions' -- that can be used to configure the scale. class Scalable (f :: * -> *) a b where -- | 'Target' @f@ is the codomain of the scale. For example, if @f@ is a scale -- that maps real numbers to real numbers, then 'Target' @f@ is -- 'Data.Functor.Identity' (a point). If it is an ordinal scale, then -- 'Target' @f@ is 'Data.H3.Extent.Extent' (an interval). type Target f :: * -> * -- | 'TargetRange' @f@ is the type of the range parameter of the scale. For -- example, if @f@ is a scale that maps real numbers to real numbers, then -- 'TargetRange' @f@ is 'Data.H3.Extent' (an interval). For ordinal scales, -- 'Target' @f@ is @[]@, a list of possible values. type TargetRange f b :: * -- | Additional parameters for the scale (other than target range). data ScaleOptions f a b :: * -- | Given 'ScaleOptions' and a 'TargetRange', produce a map 'a -> (Target f) -- b'. scale :: (ScaleOptions f) a b -> TargetRange f b -> a -> (Target f) b -- | Every function 'f :: a -> b' is a scale arrow :: (a -> b) -> ScaleOptions ((->) a) a b arrow = ArrScaleOpts instance Scalable ((->) a) a b where type Target ((->) a) = Identity type TargetRange ((->) a) b = () data ScaleOptions ((->) a) a b = ArrScaleOpts (a -> b) scale (ArrScaleOpts f) _ = Identity . f