{-# LANGUAGE FlexibleContexts, TypeFamilies, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, GADTs, UndecidableInstances #-} module Data.ProxN.VecN ( VecNClass(..) , VecN(..) ) where import Data.ProxN.Pretty import Control.Applicative import Control.Monad(liftM2) import Data.Functor import Data.Foldable import Data.Monoid import qualified Data.ProxN.Peano as P --data VecNil a = VecNil --data VecTCons v a = !a :<: !(v a) instance Show (VecN P.Zero a) where show = const "[]" instance (Show a, Show (VecN n a)) => Show (VecN (P.Succ n) a) where show (a :<: v) = "[" ++ show a ++ "]" ++ show v instance Functor (VecN P.Zero) where fmap _ VecNil = VecNil instance (Functor (VecN n)) => Functor (VecN (P.Succ n)) where fmap f (a :<: v) = f a :<: fmap f v instance Foldable (VecN P.Zero) where foldMap _ VecNil = mempty instance (Foldable (VecN n)) => Foldable (VecN (P.Succ n)) where foldMap f (a :<: v) = f a `mappend` foldMap f v instance Applicative (VecN P.Zero) where pure _ = VecNil (<*>) _ _ = VecNil instance (Applicative (VecN n)) => Applicative (VecN (P.Succ n)) where pure a = a :<: pure a (f :<: v1) <*> (a :<: v2) = f a :<: (v1 <*> v2) instance (Show a) => Pretty (VecN P.Zero a) where prettyPrint = prettyPut . show instance (Show a, Show (VecN n a)) => Pretty (VecN (P.Succ n) a) where prettyPrint = prettyPut . show class ( P.Peano n , Applicative (VecN n) , Functor (VecN n)) => VecNClass n where data VecN n :: * -> * distance2 :: (Num a) => VecN n a -> VecN n a -> a vecCartProd :: VecN n [a] -> [VecN n a] fromList :: [a] -> Maybe (VecN n a) instance (VecNClass r) => VecNClass (P.Succ r) where data VecN (P.Succ r) a = !a :<: !(VecN r a) distance2 (a :<: v1) (b :<: v2) = (a - b) ^ (2 :: Int) + distance2 v1 v2 vecCartProd (as :<: vs) = liftM2 (:<:) as (vecCartProd vs) -- [ a :<: v | a <- as -- , v <- vecCartProd vs ] fromList [] = Nothing fromList (a : as) = (a :<:) <$> fromList as instance VecNClass P.Zero where data VecN P.Zero a = VecNil distance2 _ _ = 0 vecCartProd VecNil = [VecNil] fromList _ = Just VecNil