I've made myself a "ZipVector
" style Applicative
on finite Vector
s which uses a sum type to glue finite vectors to Unit
s which model "infinite" vectors.
data ZipVector a = Unit a | ZipVector (Vector a)
deriving (Show, Eq)
instance Functor ZipVector where
fmap f (Unit a) = Unit (f a)
fmap f (ZipVector va) = ZipVector (fmap f va)
instance Applicative ZipVector where
pure = Unit
Unit f <*> p = fmap f p
pf <*> Unit x = fmap ($ x) pf
ZipVector vf <*> ZipVector vx = ZipVector $ V.zipWith ($) vf vx
This will probably be sufficient for my needs, but I idly wanted a "Fixed Dimensional" one modeled on the applicative instances you can get with dependently typed "Vector"s.
data Point d a = Point (Vector a) deriving (Show, Eq)
instance Functor (Point d) where
fmap f (Point va) = Point (fmap f va)
instance Applicative Point where
pure = Vector.replicate reifiedDimension
Point vf <*> Point vx = Point $ V.zipWith ($) vf vx
where the d
phantom parameter is a type-level Nat
. How can I (if it's possible) write reifiedDimension
in Haskell? Moreover, again if possible, given (Point v1) :: Point d1 a
and (Point v2) :: Point d2 a
how can I get length v1 == length v2
can I get d1 ~ d2
?
How can I (if it's possible) write
reifiedDimension
in Haskell?
Using GHC.TypeLits
and ScopedTypeVariables
:
instance SingI d => Applicative (Point d) where
pure = Point . Vector.replicate reifiedDimension
where reifiedDimension = fromInteger $ fromSing (sing :: Sing d)
...
See my answer here for a full example.
Moreover, again if possible, given
(Point v1) :: Point d1 a
and(Point v2) :: Point d2 a
how can I getlength v1 == length v2
can I getd1 ~ d2
?
With Data.Vector
, no. You'd need a vector type that encodes the length in the type. The best you can do is to maintain this yourself and encapsulate it by not exporting the Point
constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With