{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} module Linear.Vector where import Data.Vector.Fixed ( Dim, Fun(..), N1, N2, N3, N4, Vector(..), construct, inspect, toList, ) import qualified Data.Vector.Fixed as V ( length, ) -- * Low-dimension vector wrappers. -- -- These wrappers are instances of 'Vector', so they inherit all of -- the userful instances defined above. But, they use fixed -- constructors, so you can pattern match out the individual -- components. data D1 a = D1 a type instance Dim D1 = N1 instance Vector D1 a where inspect (D1 x) (Fun f) = f x construct = Fun D1 data D2 a = D2 a a type instance Dim D2 = N2 instance Vector D2 a where inspect (D2 x y) (Fun f) = f x y construct = Fun D2 data D3 a = D3 a a a type instance Dim D3 = N3 instance Vector D3 a where inspect (D3 x y z) (Fun f) = f x y z construct = Fun D3 data D4 a = D4 a a a a type instance Dim D4 = N4 instance Vector D4 a where inspect (D4 w x y z) (Fun f) = f w x y z construct = Fun D4 -- | Unsafe indexing. -- -- Examples: -- -- >>> let v1 = D2 1 2 -- >>> v1 ! 1 -- 2 -- (!) :: (Vector v a) => v a -> Int -> a (!) v1 idx = (toList v1) !! idx -- | Safe indexing. -- -- Examples: -- -- >>> let v1 = D3 1 2 3 -- >>> v1 !? 2 -- Just 3 -- >>> v1 !? 3 -- Nothing -- (!?) :: (Vector v a) => v a -> Int -> Maybe a (!?) v1 idx | idx < 0 || idx >= V.length v1 = Nothing | otherwise = Just $ v1 ! idx