Added tool to join vectors

This commit is contained in:
2022-10-09 13:21:45 +02:00
parent fe0cb018cc
commit a80a7f749e
2 changed files with 98 additions and 1 deletions

View File

@@ -0,0 +1,95 @@
{-# LANGUAGE TypeFamilies, ViewPatterns, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, FlexibleContexts, UndecidableInstances #-}
module Petzval.Internal.Vec where
import Linear
-- | Vector that can be shrunk by one element.
-- Laws:
-- @
-- (uncurry vextR) . vshrinkR = id
-- (uncurry vextL) . vshrinkL = id
-- @
class VExtend (v :: * -> *) where
type VExtended (v :: * -> *) :: * -> *
vextR :: v a -> a -> VExtended v a
vextL :: a -> v a -> VExtended v a
class VShrink (v :: * -> *) where
type VShrunk (v :: * -> *) :: * -> *
vshrinkR :: v a -> (VShrunk v a, a)
vshrinkL :: v a -> (a, VShrunk v a)
class VEmpty (v :: * -> *)
class VConcat (v1 :: * -> *) (v2 :: * -> *) where
type VConcated v1 v2 :: * -> *
vconcat :: v1 a -> v2 a -> (VConcated v1 v2) a
instance {-# OVERLAPPED #-} VConcat V0 v where
type VConcated V0 v = v
vconcat V0 v = v
-- I'd love for this to work, but alas, it's incoherent because the constraints are ignored during matching
--instance {-# OVERLAPPABLE #-} (VShrink v1, VExtend v2, VConcat (VShrunk v1) (VExtended v2)) => VConcat v1 v2 where
-- type VConcated v1 v2 = VConcated (VShrunk v1) (VExtended v2)
-- vconcat (vshrinkR -> (v1, a)) v2 = vconcat v1 $ vextL a v2
instance (VExtend v) => VConcat V1 v where
type VConcated V1 v = VExtended v
vconcat (V1 a) v = vextL a v
instance (VExtend v, VConcat V1 (VExtended v)) => VConcat V2 v where
type VConcated V2 v = VConcated V1 (VExtended v)
vconcat (vshrinkR -> (v1,a)) v2 = v1 `vconcat` vextL a v2
instance (VExtend v, VConcat V2 (VExtended v)) => VConcat V3 v where
type VConcated V3 v = VConcated V2 (VExtended v)
vconcat (vshrinkR -> (v1,a)) v2 = v1 `vconcat` vextL a v2
instance (VExtend v, VConcat V3 (VExtended v)) => VConcat V4 v where
type VConcated V4 v = VConcated V3 (VExtended v)
vconcat (vshrinkR -> (v1,a)) v2 = v1 `vconcat` vextL a v2
-- shrink instances
instance VShrink V1 where
type VShrunk V1 = V0
vshrinkL (V1 a) = (a, V0)
vshrinkR (V1 a) = (V0, a)
instance VShrink V2 where
type VShrunk V2 = V1
vshrinkL (V2 a b) = (a, V1 b)
vshrinkR (V2 a b) = (V1 a, b)
instance VShrink V3 where
type VShrunk V3 = V2
vshrinkL (V3 a b c) = (a, V2 b c)
vshrinkR (V3 a b c) = (V2 a b, c)
instance VShrink V4 where
type VShrunk V4 = V3
vshrinkL (V4 a b c d) = (a, V3 b c d)
vshrinkR (V4 a b c d) = (V3 a b c, d)
-- extend instances
instance VExtend V0 where
type VExtended V0 = V1
vextL a V0 = V1 a
vextR V0 a = V1 a
instance VExtend V1 where
type VExtended V1 = V2
vextL e (V1 a) = V2 e a
vextR (V1 a) e = V2 a e
instance VExtend V2 where
type VExtended V2 = V3
vextL e (V2 a b) = V3 e a b
vextR (V2 a b) e = V3 a b e
instance VExtend V3 where
type VExtended V3 = V4
vextL e (V3 a b c) = V4 e a b c
vextR (V3 a b c) e = V4 a b c e