ComonadSheet-0.3.0.0: Control/Comonad/Sheet/Names.hs
{- |
Module : Control.Comonad.Sheet.Names
Description : Names for the relevant aspects of some smaller dimensions (currently up to 4).
Copyright : Copyright (c) 2014 Kenneth Foner
Maintainer : kenneth.foner@gmail.com
Stability : experimental
Portability : non-portable
This module defines names to be used manipulating n-dimensional sheets. Currently, names are defined for dimensions
of 4 and fewer. Below is a summary of the names currently defined in this module. Template Haskell to define these names for new dimension numbers is coming soon!
=Dimension 1:
* 'Sheet1' is the type of a 1-dimensional sheet
* 'left' (negative) and 'right' (positive) are directions
* 'leftBy' and 'rightBy' define relative position by some integer argument
* 'columnAt' defines absolute position at a given column
* 'column' retrieves the current column index
* 'd1' coerces a 1-or-fewer-dimensional reference to a 1-dimensional reference
=Dimension 2:
* 'Sheet2' is the type of a 2-dimensional sheet
* 'above' (negative) and 'below' (positive) are directions
* 'aboveBy' and 'belowBy' define relative position by some integer argument
* 'rowAt' defines absolute position at a given row
* 'row' retrieves the current row index
* 'd2' coerces a 2-or-fewer-dimensional reference to a 2-dimensional reference
=Dimension 3:
* 'Sheet3' is the type of a 3-dimensional sheet
* 'inward' (negative) and 'outward' (positive) are directions
* 'inwardBy' and 'outwardBy' define relative position by some integer argument
* 'levelAt' defines absolute position at a given level
* 'level' retrieves the current level index
* 'd3' coerces a 3-or-fewer-dimensional reference to a 3-dimensional reference
=Dimension 4:
* 'Sheet4' is the type of a 4-dimensional sheet
* 'ana' (negative) and 'kata' (positive) are directions
* 'anaBy' and 'kataBy' define relative position by some integer argument
* 'spaceAt' defines absolute position at a given space
* 'space' retrieves the current space index
* 'd4' coerces a 4-or-fewer-dimensional reference to a 4-dimensional reference
-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Control.Comonad.Sheet.Names
( Sheet1 , here1 , d1 , columnAt , column , rightBy , leftBy , right , left
, Sheet2 , here2 , d2 , rowAt , row , aboveBy , belowBy , above , below
, Sheet3 , here3 , d3 , levelAt , level , inwardBy , outwardBy , inward , outward
, Sheet4 , here4 , d4 , spaceAt , space , anaBy , kataBy , ana , kata
) where
import Control.Comonad.Sheet.Reference
import Data.Numeric.Witness.Peano
import Data.Stream.Tape
import Control.Comonad.Sheet.Indexed
import Data.Functor.Nested
import Data.List.Indexed
-- One dimension...
type Rel1 = Relative :-: Nil
type Nat1 = Succ Zero
nat1 :: Natural Nat1
nat1 = reifyNatural
type Sheet1 = Nested (NestedNTimes Nat1 Tape)
type ISheet1 = Indexed (NestedNTimes Nat1 Tape)
here1 :: RefList Rel1
here1 = Rel 0 :-: ConicNil
d1 :: (CombineRefLists Rel1 x) => RefList x -> RefList (Rel1 & x)
d1 = (here1 &)
columnAt :: Int -> RefList (Absolute :-: Nil)
columnAt = dimensional nat1 . Abs
column :: (Zero < NestedCount ts) => Indexed ts x -> Int
column = getRef . nth Zero . index
rightBy, leftBy :: Int -> RefList Rel1
rightBy = dimensional nat1 . Rel
leftBy = rightBy . negate
right, left :: RefList Rel1
right = rightBy 1
left = leftBy 1
-- Two dimensions...
type Rel2 = Relative :-: Rel1
type Nat2 = Succ Nat1
nat2 :: Natural Nat2
nat2 = reifyNatural
type Sheet2 = Nested (NestedNTimes Nat2 Tape)
type ISheet2 = Indexed (NestedNTimes Nat2 Tape)
here2 :: RefList Rel2
here2 = Rel 0 :-: here1
d2 :: (CombineRefLists Rel2 x) => RefList x -> RefList (Rel2 & x)
d2 = (here2 &)
rowAt :: Int -> RefList (Tack Absolute Rel1)
rowAt = dimensional nat2 . Abs
row :: (Nat1 < NestedCount ts) => Indexed ts x -> Int
row = getRef . nth nat1 . index
belowBy, aboveBy :: Int -> RefList Rel2
belowBy = dimensional nat2 . Rel
aboveBy = belowBy . negate
below, above :: RefList Rel2
below = belowBy 1
above = aboveBy 1
-- Three dimensions...
type Rel3 = Relative :-: Rel2
type Nat3 = Succ Nat2
nat3 :: Natural Nat3
nat3 = reifyNatural
type Sheet3 = Nested (NestedNTimes Nat3 Tape)
type ISheet3 = Indexed (NestedNTimes Nat3 Tape)
here3 :: RefList Rel3
here3 = Rel 0 :-: here2
d3 :: (CombineRefLists Rel3 x) => RefList x -> RefList (Rel3 & x)
d3 = (here3 &)
levelAt :: Int -> RefList (Tack Absolute Rel2)
levelAt = dimensional nat3 . Abs
level :: (Nat2 < NestedCount ts) => Indexed ts x -> Int
level = getRef . nth nat2 . index
outwardBy, inwardBy :: Int -> RefList Rel3
outwardBy = dimensional nat3 . Rel
inwardBy = outwardBy . negate
outward, inward :: RefList Rel3
outward = outwardBy 1
inward = inwardBy 1
-- Four dimensions...
type Rel4 = Relative :-: Rel3
type Nat4 = Succ Nat3
nat4 :: Natural Nat4
nat4 = reifyNatural
type Sheet4 = Nested (NestedNTimes Nat4 Tape)
type ISheet4 = Indexed (NestedNTimes Nat4 Tape)
here4 :: RefList Rel4
here4 = Rel 0 :-: here3
d4 :: (CombineRefLists Rel4 x) => RefList x -> RefList (Rel4 & x)
d4 = (here4 &)
spaceAt :: Int -> RefList (Tack Absolute Rel3)
spaceAt = dimensional nat4 . Abs
space :: (Nat3 < NestedCount ts) => Indexed ts x -> Int
space = getRef . nth nat3 . index
anaBy, kataBy :: Int -> RefList Rel4
anaBy = dimensional nat4 . Rel
kataBy = anaBy . negate
ana, kata :: RefList Rel4
ana = anaBy 1
kata = kataBy 1