一个示例值:[[1, 2], [1]]
在这里,我知道有2个列表,第一个列表的长度为2,而第二个列表的长度为1。理想情况下,此函数将计算这些类型:
func : (n ** Vect n Nat) -> Type
但是我不知道怎么写。我很确定这与依赖对有关,但是我不确定如何编写。
为澄清起见,我知道可以简单地使用(n ** Vect n (p ** Vect p Double))
作为示例值的类型。但是,n
仅限制列表的数目,而不限制其元素的数目,因为在列表内部,p
可以是任何东西。我很可能需要某些东西,其中依赖对的第一个元素是长度的向量,而不仅仅是列表的数量。像(Vect n Nat ** Vect n (Vect m Double))
这样的东西-每个m
是第一个向量的对应元素。
答案 0 :(得分:3)
您可以定义一个新的向量类型,该向量类型在每个位置都可能包含索引类型不同的索引元素:
import Prelude
import Data.Vect
-- heterogeneously indexed vector
data IVect : Vect n ix -> (ix -> Type) -> Type where
Nil : IVect Nil b
(::) : b i -> IVect is b -> IVect (i :: is) b
-- of which a special case is a vector of vectors
VVect : Vect n Nat -> Type -> Type
VVect is a = IVect is (flip Vect a)
test1 : VVect [2, 2, 2] Nat
test1 = [[1, 2], [3, 4], [5, 6]]
test2 : VVect [0, 1, 2] Bool
test2 = [[], [True], [False, True]]
或者,您可以使用相关对和VVect
来定义map
,但是使用起来比较麻烦:
VVect' : Vect n Nat -> Type -> Type
VVect' {n = n} is a = (xs : Vect n (m ** Vect m a) ** (map fst xs = is))
test3 : VVect' [0, 1, 2] Bool
test3 = ([(_ ** []), (_ ** [True]), (_ ** [False, False])] ** Refl)
您可以选择使用列表还是矢量。使用列表作为内部容器,值看起来更加紧凑:
VVect'' : Vect n Nat -> Type -> Type
VVect'' {n = n} is a = (xs : Vect n (List a) ** (map length xs = is))
test4 : VVect'' [0, 1, 2] Bool
test4 = ([[], [True], [False, True]] ** Refl)