我在有限ZipVector
上做了一个“Applicative
”样式Vector
,它使用和类型将有限向量粘贴到Unit
s模型“无限” “载体。
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
这可能足以满足我的需求,但我想要一个“固定尺寸”模型,模仿你可以通过依赖类型“矢量”得到的应用实例。
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
其中d
幻像参数是类型级Nat
。我怎么能(如果可能的话)在Haskell中写reifiedDimension
?此外,如果可能的话,给定(Point v1) :: Point d1 a
和(Point v2) :: Point d2 a
如何才能获得length v1 == length v2
d1 ~ d2
?
答案 0 :(得分:4)
我怎样才能(如果可能的话)在Haskell中写
reifiedDimension
?
使用GHC.TypeLits
和ScopedTypeVariables
:
instance SingI d => Applicative (Point d) where
pure = Point . Vector.replicate reifiedDimension
where reifiedDimension = fromInteger $ fromSing (sing :: Sing d)
...
有关完整示例,请参阅my answer here。
此外,如果可能的话,给定
(Point v1) :: Point d1 a
和(Point v2) :: Point d2 a
如何才能获得length v1 == length v2
d1 ~ d2
?
Data.Vector
,没有。您需要一个矢量类型来编码类型中的长度。您可以做的最好的事情就是自己维护它并通过不导出Point
构造函数来封装它。