Haskell 独立输入';ZipVector';应用程序

Haskell 独立输入';ZipVector';应用程序,haskell,types,vector,dependent-type,Haskell,Types,Vector,Dependent Type,我在有限向量上做了一个“ZipVector”风格的Applicative,它使用一个求和类型将有限向量粘附到单元,该单元模拟“无限”向量 数据ZipVector a=单位a | ZipVector(向量a) 推导(显示,等式) 实例函子ZipVector,其中 fmap f(单位a)=单位(单位a) fmap f(ZipVector va)=ZipVector(fmap f va) 实例应用程序ZipVector,其中 纯=单位 单位fp=fmap fp pf单位x=fmap($x)pf Zip

我在有限向量上做了一个“
ZipVector
”风格的
Applicative
,它使用一个求和类型将有限向量粘附到
单元,该单元模拟“无限”向量

数据ZipVector a=单位a | ZipVector(向量a)
推导(显示,等式)
实例函子ZipVector,其中
fmap f(单位a)=单位(单位a)
fmap f(ZipVector va)=ZipVector(fmap f va)
实例应用程序ZipVector,其中
纯=单位
单位fp=fmap fp
pf单位x=fmap($x)pf
ZipVector vf ZipVector vx=ZipVector$V.zipWith($)vf vx
这可能足以满足我的需要,但我只是想要一个“固定维度”的模型,该模型是根据依赖类型的“Vector”得到的应用程序实例建模的

数据点d a=点(向量a)导出(显示,等式)
实例函子(点d),其中
fmap f(点va)=点(fmap f va)
实例应用点
纯=向量。复制重新定义尺寸
点vf点vx=点$V.zipWith($)vf vx
其中
d
phantom参数是类型级别
Nat
。我如何(如果可能的话)在Haskell中编写
reifiedDimension
?此外,如果可能,再次给出
(点v1)::点d1a
(点v2)::点d2a
如何获得
长度v1==长度v2
我可以获得
d1~d2

我如何(如果可能的话)在Haskell中编写
reifiedDimension

使用
GHC.TypeLits
ScopedTypeVariables

instance SingI d => Applicative (Point d) where
  pure = Point . Vector.replicate reifiedDimension
    where reifiedDimension = fromInteger $ fromSing (sing :: Sing d)
  ...
有关完整示例,请参见

此外,如果可能,再次给出
(点v1)::点d1a
(点v2)::点d2a
如何获得
长度v1==长度v2
我可以获得
d1~d2


对于
Data.Vector
,不需要。您需要一个矢量类型来编码类型中的长度。你能做的最好的事情就是自己维护它,并通过不导出
构造函数来封装它。

你的意思是说拥有一个像
toP::Vector a->Point d a
这样的智能构造函数,它反映了
d::Sing(Vector.length v)
?我一直试图让它工作,但它失败了,我还不能确切地理解类型错误是怎么说的;pLen\uuSing
GHC抱怨说,由于使用pLen而导致的(SingI Nat d0)实例不存在。另外,当类似的函数似乎起作用时,为什么要包括
Maybe
?添加
可以确保类型中的长度与实际长度匹配。如果你可以使用任何一个旧的向量,那么使用智能构造函数就没有多大意义了。我想要FMAPPLEN。顶部===刚刚好。V.长度
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
instance SingI d => Applicative (Point d) where
  pure = Point . Vector.replicate reifiedDimension
    where reifiedDimension = fromInteger $ fromSing (sing :: Sing d)
  ...